Since July 5, 2023, BigQuery compute is priced one of two ways: on-demand, where you pay per tebibyte scanned, or BigQuery Editions — Standard, Enterprise, or Enterprise Plus — where you pay per slot-hour for capacity that autoscales between a baseline and a maximum. Flat-rate and flex slots are gone. If your cost model, or your cost intuition, was built before 2023, this guide is the reset.
The three editions in one table
| Standard | Enterprise | Enterprise Plus | |
|---|---|---|---|
| Intended for | Dev, test, and simple analytics | Production analytics | Regulated, mission-critical workloads |
| Autoscaling | Yes | Yes | Yes |
| Maximum slots per reservation | 1,600 | No edition-imposed cap (project quotas apply) | No edition-imposed cap |
| Commitments (discounted 1- and 3-year) | No | Yes | Yes |
| Column-level and row-level security | No | Yes | Yes |
| Materialized views, BI Engine, BigQuery ML | Limited | Yes | Yes |
| Cross-region disaster recovery, CMEK, ~99.99% SLA | No | Partial | Yes |
Prices differ by region and change over time — always confirm the current slot-hour rates on the BigQuery pricing page. The shape of the decision, however, is stable, and that is what the worked example below illustrates.
A worked example: one workload, priced three ways
Assume a US-region analytics estate with the following monthly profile, pulled from INFORMATION_SCHEMA.JOBS:
- 400 TiB scanned per month across ad-hoc analyst queries and dashboards
- Slot usage averaging 250 slots during a 12-hour business day, near zero overnight, with a daily ELT window that spikes to 800 slots for 90 minutes
- 22 business days a month
On-demand. 400 TiB at the on-demand rate (in the US, a few dollars per TiB, with the first TiB free each month) — call it on the order of a few thousand dollars per month. Cost tracks bytes scanned only; slot usage is irrelevant, and so is elapsed time.
Standard edition, autoscaled. Baseline 0 slots, max 1,000. Billed slot-hours approximate the area under the usage curve: roughly 250 slots × 12 hours × 22 days ≈ 66,000 slot-hours, plus the ELT spike at 800 slots × 1.5 hours × 22 days ≈ 26,400 slot-hours, plus autoscaler rounding (scaling happens in 50-slot steps and each step is billed for a minimum of one minute). Multiply by the Standard per-slot-hour rate.
Enterprise edition with a 1-year commitment. Commit 200 slots at the discounted committed rate for the steady daytime load, autoscale the remainder (max 1,000) at the pay-as-you-go Enterprise rate. You pay for the 200 committed slots around the clock, including overnight when they sit idle, in exchange for a lower hourly rate.
When you run the arithmetic with current regional prices, three things usually fall out:
- Bursty, scan-heavy analyst workloads with low slot utilisation are cheapest on-demand, and get cheaper still once partitioning and clustering cut bytes scanned.
- Steady ELT and scheduled-query workloads that keep slots busy are cheaper on an edition, and cheaper again with a commitment sized to the floor of the load, not its peak.
- Enterprise is rarely justified by price alone; it is justified by features — row-level security, BI Engine, materialised view rewrites — that you are actually using.
The honest answer for this estate is a mix: a Standard or Enterprise reservation assigned to the ELT project, and the analyst projects left on-demand.
Mixing on-demand and reservations
Billing model is chosen per project through reservation assignments, so a single organisation can run both:
-- Create an autoscaling Enterprise reservation in the admin project
CREATE RESERVATION `admin-project.region-us.elt-prod`
OPTIONS (
edition = 'ENTERPRISE',
slot_capacity = 100, -- baseline (committed or pay-as-you-go)
autoscale_max_slots = 600 -- cap for the autoscaler
);
-- Assign only the ELT project to it; every unassigned project stays on-demand
CREATE ASSIGNMENT `admin-project.region-us.elt-prod.elt-pipelines`
OPTIONS (
assignee = 'projects/acme-elt-prod',
job_type = 'QUERY'
);
Assignments can also be scoped by job type (PIPELINE for load and export jobs, ML_EXTERNAL for remote model calls), which lets you keep LLM-function spend inside a capped reservation while queries run on-demand.
How the autoscaler actually behaves
- Slots scale up in increments of 50, within seconds of demand appearing, up to
autoscale_max_slots. - Each scale-up is billed for a minimum of one minute; scale-down happens after demand drops, so a thirty-second spike costs one minute of the added slots.
- Baseline slots (
slot_capacity) are always billed whether used or not. A baseline of zero is valid and is the right starting point when you do not yet know the floor. - Idle slots in one reservation are not shared with another by default; if you split workloads across reservations, set
ignore_idle_slots = falseon the reservations that should borrow.
Watch INFORMATION_SCHEMA.RESERVATION_TIMELINE and JOBS_TIMELINE for the first two weeks: if the autoscaler spends most of the day at its maximum, raise the cap or move workloads; if it never exceeds the baseline, lower the baseline.
Migrating from a flat-rate mindset
Teams coming from the old flat-rate world tend to make three mistakes:
- Committing to the peak. Flat-rate forced you to buy for the worst hour. With autoscaling, commit to the floor and let the autoscaler cover the peak.
- One reservation for everything. Separate production ELT from analyst exploration so a runaway ad-hoc query cannot starve the nightly load; use assignments per project.
- Ignoring on-demand. For low-utilisation projects, on-demand with
maximum_bytes_billedset per query is often both cheaper and safer than a reservation.
Putting it together
Export INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION for a representative month, aggregate total_bytes_billed and total_slot_ms by project and hour, and price each project under each model with current rates. The project-level answers will differ — that is the point. If you would rather have us run the benchmark and hand you the table, our cost optimization service does exactly that; contact us to start.