Google Cloud billing
How do I export Google Cloud billing to BigQuery?
Google Cloud billing data exports to BigQuery in batches throughout the day, but it isn't real-time: usage details typically take up to 24 hours to land, and when you first turn the export on, catching up on retroactive data can take up to 5 days. Batch loading that data into BigQuery is free, but you'll pay normal BigQuery storage and query charges once it's there.
Setting up the export takes about five minutes in the Google Cloud console. Once the tables populate, you get raw, hourly line items for every service, SKU and project tied to your billing account.
Choose the right export type
Google Cloud gives you three options for usage and cost exports, plus a dedicated pricing export and Committed Use Discount (CUD) metadata. You can route standard usage, detailed usage and pricing data into the same BigQuery dataset.
The standard export gives you account IDs, invoice dates, services, SKUs, project IDs, labels, locations, costs, usage amounts, credits and adjustments. It's meant for broad trend analysis across your projects.
The detailed export contains everything in the standard export plus resource-level information, such as the specific virtual machine or SSD disk generating each line item. If you run Google Kubernetes Engine (GKE), detailed export includes Compute Engine resources automatically, but viewing a full breakdown of GKE cluster costs requires you to also enable cost allocation for GKE. Detailed export tables get large quickly. Because BigQuery charges for the volume of data scanned per query, querying a detailed export table often costs more than running the same aggregate query against a standard table.
There is also a FOCUS usage cost export, currently in Preview. It loads detailed data normalized to the FinOps Open Cost and Usage Specification into an immutable dataset that Google provides and pays for. It carries no storage costs for the most recent two years of data, though it has an automatic two-year time-to-live (TTL) policy that drops data older than two years unless you copy it into a customer-owned table.
| Export type | Granularity | Storage cost | Retroactive data on setup |
|---|---|---|---|
| Standard usage | Account, project, service, SKU, labels | Standard BigQuery storage | Previous and current month (multi-region only) |
| Detailed usage | Standard fields plus individual resources (VMs, SSDs) | Standard BigQuery storage | Previous and current month (multi-region only) |
| FOCUS (Preview) | Detailed fields normalized to FOCUS specification | Free for 2 years (Google-managed dataset) | Previous and current month (multi-region only) |
| Pricing data | List prices, SKU descriptions, tiers | Standard BigQuery storage | None (only dates after setup) |
| CUD metadata (Preview) | Daily committed use discount metadata | Uses an auto-created BigQuery linked dataset | Daily export |
Required permissions before you start
Before clicking around the console, verify your Identity and Access Management (IAM) permissions across both the billing account and the target project.
To export standard or detailed usage data, you need:
- Either the Billing Account Costs Manager role or the Billing Account Administrator role on the target Cloud Billing account.
- The BigQuery User role on the Google Cloud project that will hold your BigQuery dataset.
If you also want to export Cloud Billing pricing data or CUD metadata, the permission requirements are stricter:
- The Billing Account Administrator role on the target Cloud Billing account.
- The BigQuery Admin role on the dataset project.
- The
resourcemanager.projects.updatepermission on the dataset project, which is included in roles/editor. - The BigQuery Data Transfer Service API enabled on that dataset project. If you aren't exporting pricing data, you don't need this API.
If you decide to spin up a brand-new project inside an Organization or Folder to keep your billing data isolated, your account needs the Project Creator role (roles/resourcemanager.projectCreator), which provides the resourcemanager.organizations.get and resourcemanager.projects.create permissions.
Step-by-step: set up the BigQuery export
The project you pick to hold your dataset must have billing enabled, and it must be linked to the exact Cloud Billing account whose usage you're exporting. Both standard and detailed exports will automatically cover usage and costs across all projects paid for by that billing account.
1. Create the BigQuery dataset
Go to BigQuery in the Google Cloud console under your designated billing project. Create a new dataset.
Pay close attention to two settings here:
- Dataset location: Cloud Billing export supports all multi-region locations (EU or US), but only a specific subset of single-region locations. Once you create the dataset, you cannot change its location. More importantly, if you pick a multi-region location (EU or US), Google will retroactively populate data from the start of the previous calendar month. If you select a single region, Google will not add retroactive data at all; you will only see records incurred from the day you enable the export onward.
- Table expiration: Make sure the "Enable table expiration" checkbox is cleared. If you leave table expiration enabled with a set number of days, BigQuery will automatically delete the tables Google creates after that window passes.
Note that for CUD metadata export, you don't create a dataset ahead of time; Google creates an automated linked dataset during configuration.
2. Enable the export in Cloud Billing
Open the Cloud Billing console, select your billing account, and navigate to Billing export.
- Under Standard usage cost or Detailed usage cost, click Edit settings (or Configure export).
- Select your project and your newly created dataset.
- Save the configuration.
Once you click save, Google automatically grants the dataset owner role to the billing service account: billing-export-bigquery@system.gserviceaccount.com for usage and FOCUS datasets, or cloud-account-pricing@cloud-account-pricing.iam.gserviceaccount.com for pricing datasets. If you run BigQuery row-level security policies on these tables later, you must create a row access policy granting full access to serviceAccount:billing-export-bigquery@system.gserviceaccount.com using FILTER USING (TRUE).
Google will automatically create the tables inside your dataset. Standard usage creates gcp_billing_export_v1_, detailed usage creates gcp_billing_export_resource_v1_, and pricing export creates cloud_pricing_export.
If you ever need to change the project or dataset later, you have to disable the export first, then re-enable it with the new target. Google will not copy previously exported records over to the new dataset; you have to manually join the old and new tables to query across the boundary.
How fresh is the data?
Billing data in BigQuery is never real-time. Cloud Billing collects records throughout the day in batches, but services like Compute Engine, Google Maps Platform, Google AI Studio and Firebase report usage at varying intervals.
Here is what to expect for timing and propagation delays:
- Initial backfill: When you first enable a standard, detailed or FOCUS export, data starts arriving within a few hours. Catching up on the current and previous month's retroactive data can take up to 5 days.
- Pricing export delays: When you enable the pricing export, records can take up to 48 hours to appear, and pricing data is never retroactive.
- Daily reporting lag: Most usage charges appear within a day, but individual product records can take more than 24 hours to reach your dataset.
- Granularity: Usage and costs appear with hourly granularity. In the schema,
usage_start_timeandusage_end_timemark the start and end of that hourly window. - Resource tags and labels: Tags take up to an hour to propagate to billing exports. If a resource exists for less than an hour, or if a tag was applied and removed within an hour, that tag might not show up. For user labels, cost data only tracks usage from the date and time the label was actually attached to the resource; it never applies retroactively.
If you need fast alerts on sudden usage spikes, relying solely on BigQuery exports leaves an unavoidable multi-hour blind spot. You can pair the export with live operational metrics to catch runaway workloads earlier, or see How do I set up Google Cloud budget alerts that reach me in time? for native alert thresholds.
Querying your export tables accurately
Schema updates happen over time as Google adds new fields to exports. Because of this, Google recommends creating custom BigQuery views on top of the exported tables to feed dashboards and queries, rather than pointing raw queries directly at the tables. That way, a schema addition won't break upstream reports.
When writing SQL against the raw tables, watch out for invoice matching and floating-point math:
Matching the official monthly invoice
Don't group by usage_start_time, usage_end_time or export_time if you want your numbers to match your official monthly bill. Services sometimes report usage late, and late-reported usage rolls over to the next calendar month's bill. To match the invoice exactly, filter on invoice.month (formatted as YYYYMM).
Avoiding floating-point errors
The cost and credits.amount fields are floating-point numbers. Directly summing them causes precision drift. The official pattern is to multiply each value by 1,000,000, cast it to int64, sum the integers, and then divide back out by 1,000,000.
SELECT
invoice.month,
service.description AS service_name,
SUM(CAST(cost * 1000000 AS INT64)) / 1000000 AS total_cost_exact
FROM
`my-billing-export-project.billing_export.gcp_billing_export_v1_0123AB_CDEF45_6789AB`
WHERE
invoice.month = '202611'
GROUP BY
1, 2
ORDER BY
total_cost_exact DESC;Connecting your export to Costbrake
BigQuery gives you complete SQL access, but it's fundamentally retrospective. If an autonomous script or an AI agent gets stuck in a loop, waiting up to 24 hours for billing data to settle means you only see the cost after the damage is done.
Costbrake watches what you spend across 23 cloud, AI and SaaS providers, including Google Cloud (with the Gemini API and Vertex AI), AWS, Azure, OpenAI and Anthropic. It alerts you on spending spikes, budget thresholds, month-end forecasts and unexpected new charges.
For Google Cloud, Costbrake reads your BigQuery billing export and pairs it with live Cloud Monitoring usage estimates for the Gemini API, Vertex AI, Cloud Run and Cloud Run functions. That bridges the gap while BigQuery batches are delayed. It queries the export about once an hour and fills the hours since with live Cloud Monitoring estimates for the Gemini API, Vertex AI, Cloud Run and Cloud Run functions: hourly on the Free plan, every 5 minutes on Pro and Team, and every 2 minutes during an active spike. If spend runs away, you can use Costbrake's opt-in brake to place a zero Google spend cap on a specific service in a project to halt new usage. You can see how the limits behave in Can I cap my Google Cloud spend, and how do the new spend cap budgets work?, or check Costbrake pricing for plan details.
To connect your export, tell your AI coding agent "Set up Costbrake for me so I get alerted when my cloud and AI bills spike. Follow the instructions at https://costbrake.com/agent", or run through the agent setup instructions by hand.
Questions and answers
Is Google Cloud billing export to BigQuery free?
Batch loading the billing records into your BigQuery dataset is free of charge. You only pay standard BigQuery rates for data storage and the query compute you consume when reading the tables, though FOCUS exports carry free storage for their first two years.
How long does billing data take to show up in BigQuery?
Usage and cost records typically show up within a day, though individual services can take more than 24 hours. When you first configure the export, raw data starts trickling in within a few hours, but backfilling current and previous month history can take up to 5 days.
Can I backfill my entire historical billing data into BigQuery?
No. Standard and detailed exports configured in US or EU multi-regions backfill only to the start of the previous calendar month. If you select a single-region location, or if you export pricing data, Google does not backfill any past data.
What is the difference between standard and detailed export?
Standard export provides SKU-level, service-level and project-level totals with labels and locations. Detailed export adds resource-level identification, pointing directly to individual compute instances and storage disks, which generates much larger datasets and potentially higher BigQuery query scan costs.
Why do my BigQuery query totals disagree with my monthly invoice?
Querying on timestamp columns like usage_start_time captures usage when it happened, but late-reported records are often billed on the following month's invoice. Filter and sum by invoice.month instead of timestamps to match the invoice numbers.
Sources
Updated