DEV Community

Vlad Z
Vlad Z

Posted on

BigQuery is the easiest way to burn a budget by accident

BigQuery is one of the most powerful tools in GCP and one of the easiest ways to accidentally generate a very large bill

The power is real. You can query terabytes of data in seconds. The cost implication of that power is also real when queries aren't written carefully

BigQuery has two pricing models. On-demand charges per TB of data processed. Capacity pricing charges for reserved slots regardless of queries run

For most teams starting out, on-demand is what they're using. And on-demand pricing punishes full table scans

A query that selects every column from a 500GB table processes 500GB of data and charges you accordingly. A query that selects only the three columns you actually need from a partitioned table that filters to the relevant date range might process 2GB of data

Same result. Very different cost

This is the BigQuery optimization that matters most: query efficiency

Use column selection instead of SELECT *. Always. The cost difference on large tables is not marginal

Partition your tables and use partition filters in your queries. BigQuery will only scan the relevant partitions. A date-partitioned table queried with a date filter processes only the data in those dates

Cluster your tables on the columns most frequently used in WHERE clauses and JOINs. Clustering reduces the data scanned for filtered queries

The second optimization: control who can run what

Uncontrolled BigQuery access means analysts running expensive exploratory queries against production data at full scale. Query costs that belong to individual analyses ending up on the company bill with no visibility into what generated them

Column-level access controls, project-level quotas on bytes processed, and requiring query review for tables above a certain size - these are organizational controls but they have direct cost implications

BigQuery's built-in INFORMATION_SCHEMA views let you see exactly which queries are processing the most data and which users are generating the most cost

Look at that data. It will tell you where to focus

Top comments (2)

Collapse
 
elimio profile image
ELIM •

Good list. Three guards that turn the "project-level quotas" point into something each query enforces on its own:

  • bq query --dry_run --use_legacy_sql=false '...' prints how many bytes a query would process before it runs, at no cost. The console shows the same estimate in the top right of the editor.
  • --maximum_bytes_billed=10000000000 (10 GB) on a query makes BigQuery refuse anything that would bill more instead of running it. A forgotten SELECT * fails fast rather than showing up on the invoice.
  • ALTER TABLE dataset.events SET OPTIONS (require_partition_filter = TRUE); makes a query without a partition filter an error on that table, so the date filter you describe is no longer optional.

For the review step, region-us.INFORMATION_SCHEMA.JOBS has total_bytes_billed and user_email per job, which makes a weekly "top 20 queries by bytes billed" report a single SELECT.

Collapse
 
vlad_z_16b6320e21f32bee0d profile image
Vlad Z •

Dry run for the bytes estimate plus maximum_bytes_billed as a hard refusal is the right pairing, one tells you before you run it and the other stops you if you ignore the warning anyway, require_partition_filter closes the gap where someone skips both

Does INFORMATION_SCHEMA.JOBS catch scheduled queries and dashboards the same way it catches ad-hoc ones, or do service accounts running on a schedule tend to hide in a different place?