Skip to content
Finitizer
Estimate what a query costs before you run it

This recipe tells you what already happened. The analyzer takes a query you have not run yet and estimates what it will scan, in your browser.

How do I attribute BigQuery cost to a team or pipeline?

Break query spend down by job label, the only allocation dimension BigQuery gives you.

Reads metadata only, a fraction of a cent to run (10 MB minimum)Reviewed against Google’s docs, 23 Oct 2026

Permissions. Needs bigquery.jobs.listAll on the project for JOBS (BigQuery Resource Viewer has it); bigquery.jobs.create to run any query (BigQuery Job User has it).

Pick the region your data is in: every INFORMATION_SCHEMA view here is qualified by region.

-- Spend by job label. Labels must be set by the client that submits the job;
-- unlabeled jobs land in the '(none)' bucket, which is the number to watch.
SELECT
  IFNULL(label.key, '(none)')                               AS label_key,
  IFNULL(label.value, '(none)')                             AS label_value,
  COUNT(*)                                                  AS jobs,
  ROUND(SUM(total_bytes_billed) / POW(1024, 4) * 6.25, 2)   AS est_on_demand_usd,
  ROUND(SUM(total_slot_ms) / 1000 / 3600, 1)                AS slot_hours
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
LEFT JOIN UNNEST(labels) AS label
WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND job_type = 'QUERY'
  AND IFNULL(statement_type, '') != 'SCRIPT'
  AND state = 'DONE'
GROUP BY label_key, label_value
ORDER BY est_on_demand_usd DESC;

What it returns

label_key / label_value
The job label pair. "(none)" is unlabeled spend.

How to read it

  • The "(none)" row is the point of this query. If it is most of your spend, allocation is not working and no amount of downstream reporting will fix it.
  • A job carrying two labels appears in two rows, so the total across rows exceeds real spend. Never sum this column, read it one label key at a time.
  • Labels are set at submission. dbt, Dataform, Airflow, and Looker can all set them. In the console, a script or session can too: SET @@query_label = 'team:finance'; labels every query after it. Interactive work is usually unlabeled because nobody does that.
  • est_on_demand_usd prices every job at $6.25/TiB. Jobs that ran on a reservation are not billed for bytes (Google calls their total_bytes_billed "informational only"), so for them the dollar figure is hypothetical and slot_hours is what they cost.

Take it further

Run this once, or have it run every day.

Finitizer evaluates this class of question continuously against your live BigQuery estate, tracks how each number moves between runs, and turns findings into assigned tasks. Read-only and keyless.

See how Finitizer works