BigQuery Cost Check
Run three INFORMATION_SCHEMA queries in your own console and get a priced BigQuery savings report: Editions vs on-demand, the query shapes that scan over and over, and which datasets to move to physical storage billing. No access needed, nothing uploaded.
Three read-only queries, about ten minutes, and a priced list of what to fix in your BigQuery bill. Everything is computed in this browser; nothing is uploaded unless you ask for the report by email.
Before you start: what to have to handShow
- A project you can list jobs in. The BigQuery Resource Viewer role is enough.
- The region your datasets live in. INFORMATION_SCHEMA is regional, so the wrong region returns nothing rather than an error.
- Thirty days of history. The queries read the last 30 days of job metadata, which is what JOBS keeps for most of a quarter.
1. Compute, hour by hour
Jobs, bytes and slot time per hour for the last 30 days. Totals only: no query text, no table names, no users.
-- Finitizer BigQuery Cost Check, query 1 of 3: compute, hourly totals only. -- Returns no query text, no table names and no user identities. SELECT TIMESTAMP_TRUNC(creation_time, HOUR) AS hour, COUNT(*) AS jobs, SUM(total_bytes_billed) AS bytes_billed, SUM(total_bytes_processed) AS bytes_processed, SUM(total_slot_ms) AS slot_ms, COUNTIF(reservation_id IS NOT NULL) AS reserved_jobs, SUM(IF(reservation_id IS NOT NULL, total_slot_ms, 0)) AS reserved_slot_ms FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) AND job_type = 'QUERY' AND statement_type != 'SCRIPT' AND total_slot_ms IS NOT NULL GROUP BY hour ORDER BY hour;
2. The 50 heaviest query shapes
Grouped by BigQuery’s hash of each query with its literals removed. A hash and counts, never the query itself.
-- Finitizer BigQuery Cost Check, query 2 of 3: the 50 heaviest query shapes. -- A shape is BigQuery's hash of the query with its literals removed, so the -- same report run with different dates is one shape. Returns the hash, never -- the query text, and a COUNT of users, never who they are. SELECT query_info.query_hashes.normalized_literals AS pattern, COUNT(*) AS runs, SUM(total_bytes_billed) AS bytes_billed, SUM(total_bytes_processed) AS bytes_processed, SUM(total_slot_ms) AS slot_ms, COUNTIF(cache_hit) AS cache_hits, COUNT(DISTINCT user_email) AS users FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) AND job_type = 'QUERY' AND statement_type != 'SCRIPT' AND total_slot_ms IS NOT NULL AND query_info.query_hashes.normalized_literals IS NOT NULL GROUP BY pattern ORDER BY bytes_processed DESC LIMIT 50;
3. Storage by dataset
Logical and physical bytes per dataset and its billing model. Dataset names are shown in the report on this page and never sent anywhere.
-- Finitizer BigQuery Cost Check, query 3 of 3: storage by dataset. -- Returns dataset names (the advice is per dataset) and byte totals. The names -- stay in your browser; an emailed report carries totals only. SELECT s.table_schema AS dataset, COUNT(*) AS tables, SUM(s.active_logical_bytes) AS active_logical_bytes, SUM(s.long_term_logical_bytes) AS long_term_logical_bytes, SUM(s.active_physical_bytes) AS active_physical_bytes, SUM(s.long_term_physical_bytes) AS long_term_physical_bytes, SUM(s.time_travel_physical_bytes) AS time_travel_physical_bytes, SUM(s.fail_safe_physical_bytes) AS fail_safe_physical_bytes, ANY_VALUE(o.option_value) AS billing_model FROM `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE s LEFT JOIN `region-us`.INFORMATION_SCHEMA.SCHEMATA_OPTIONS o ON o.schema_name = s.table_schema AND o.option_name = 'storage_billing_model' WHERE NOT s.deleted GROUP BY dataset ORDER BY SUM(s.active_logical_bytes + s.long_term_logical_bytes) DESC;
Frequently asked questions
Does the Cost Check need access to my Google Cloud account?
No. You run three read-only INFORMATION_SCHEMA queries in your own console and paste the results here. The report is computed in your browser. If you ask for it by email, only the totals and the kinds of finding are sent, never dataset names or query shapes.
What permissions do the queries need?
bigquery.jobs.listAll on the project (the BigQuery Resource Viewer role has it) for the two jobs queries, and bigquery.tables.list for the storage query. For the whole organization, the same permissions at organization level.
How much do the queries cost to run?
INFORMATION_SCHEMA queries are billed like any query, and these read 30 days of job metadata, which for most projects is a few hundred megabytes: a fraction of a cent on demand. The console shows the estimate before you run them.
How is the BigQuery efficiency score calculated?
It is the share of your estimated monthly BigQuery spend in which the check found no saving, using the middle of each saving range. 100 means nothing to fix at list prices; 60 means about 40% of the spend has a saving attached to it.
Should I switch my datasets to physical storage billing?
Only the ones that compress well. Physical billing charges about twice the rate per byte but bills compressed bytes, and adds time travel and fail-safe at the active rate. The check computes both bills for every dataset from your own byte counts and lists the ones where physical is cheaper.
Why are some savings shown as a range?
A billing-model change has an exact answer, so it is one number. Rewriting a query has not: the range is a stated assumption about how much less data the query reads after the change, and the assumption is printed next to the figure.
Related tools
The questions this one tends to raise next.
BigQuery Slot vs On-Demand Advisor
Find out whether BigQuery Editions slots would actually save you money.
OpenBigQuery Query Cost Analyzer
What this query actually costs: computed, not guessed.
OpenBigQuery FinOps Query Pack
Copy-paste SQL for the cost questions you ask at 4pm during an incident.
OpenEvery tool on this site that touches analytics and warehouses, storage and lifecycle or pricing and commitments, across every cloud.
A report is a snapshot. The bill keeps moving.
Finitizer watches BigQuery continuously: slot sizing, the queries driving scan volume, storage billing per dataset, and the savings it verifies against later bills. Read-only.
