BigQuery FinOps Query Pack

Which days had abnormal GCP spend?

Daily cost against a trailing 7-day mean, flagged by standard deviations.

Costs money to run — queries your billing export tableChecked 4 Aug 2026
WITH daily AS (
  SELECT
    DATE(usage_start_time)                                   AS usage_date,
    service.description                                      AS service,
    SUM(cost)                                                AS cost
  FROM `PROJECT.DATASET.gcp_billing_export_v1_XXXXXX_XXXXXX_XXXXXX`
  WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
  GROUP BY usage_date, service
),
stats AS (
  SELECT
    usage_date, service, cost,
    AVG(cost)    OVER w                                      AS trailing_mean,
    STDDEV(cost) OVER w                                      AS trailing_stddev
  FROM daily
  WINDOW w AS (
    PARTITION BY service ORDER BY usage_date
    ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING
  )
)
SELECT
  usage_date, service,
  ROUND(cost, 2)                                             AS cost,
  ROUND(trailing_mean, 2)                                    AS trailing_mean,
  ROUND(SAFE_DIVIDE(cost - trailing_mean, NULLIF(trailing_stddev, 0)), 2) AS z_score
FROM stats
WHERE trailing_stddev > 0
  AND SAFE_DIVIDE(cost - trailing_mean, trailing_stddev) > 3
ORDER BY usage_date DESC, z_score DESC;

What it returns

z_score
Standard deviations above the trailing 7-day mean.

How to read it

  • A z-score above 3 on a service with steady spend is worth investigating. On a service that is naturally bursty it is noise — tune the threshold per service or restrict the query to your steady ones.
  • The last day or two of the export is usually incomplete and will look like a drop. Exclude the current day.
  • This finds spikes, not slow drift. A service growing 4% a week never trips it and will still double in half a year.

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.