BigQuery - consider using on-demand pricing before purchasing reserved slots

·

By

Infracost

BigQuery - consider using on-demand pricing before purchasing reserved slots

·

By

Infracost

This FinOps policy recommends that BigQuery workloads default to on-demand pricing and defer purchasing reserved slot capacity until historical usage data justifies it. Reserved slots bill continuously for the full committed capacity whether or not a query is running, which turns idle capacity into a fixed, ongoing cost. Purchase capacity commitments only after slot utilization metrics show a workload consistently needs dedicated capacity.

Attribute

Detail

Cloud Provider

Google Cloud (GCP)

Resource Type

BigQuery reservations and capacity commitments

Terraform Attribute

slot_capacity on google_bigquery_reservation

Compliant Value

No reservation created until sustained utilization justifies one

Cost Impact

Reserved slots bill continuously regardless of query volume; on-demand bills only for bytes scanned

Why This Policy Matters

How It Helps Reduce Cloud Costs

BigQuery's flat-rate model bills for committed slot capacity every second the reservation exists, independent of whether any query consumes it. Reservations are purchased in a minimum block of 100 slots, in increments of 100, so there is no way to commit to less capacity than that floor.

On-demand pricing works differently. It charges only for the bytes scanned by each query, and Google's own documentation notes that on-demand customers typically have access to a large shared slot pool, often 2,000 slots or more, without purchasing anything. For workloads that run intermittently or whose volume is still unpredictable, this generally provides enough headroom without any dedicated commitment.

Reserved slots are a discount mechanism for proven, steady demand. They are not a performance requirement, and treating them as a default is how idle capacity quietly becomes a permanent line item.

Potential Savings

Because a reservation is billed for its full committed size continuously, a workload that only runs a few hours a day, or only during a specific reporting window, rarely justifies dedicated capacity. The gap between the slots paid for and the slots actually used during idle hours is where this policy recovers cost.

Teams that wait for 30 days or more of slot utilization data before purchasing a commitment consistently size reservations closer to real demand. Teams that provision ahead of adoption tend to carry unused capacity for months.

Implementation Guide

Infrastructure-as-Code Example (Terraform)

The following examples show a reservation purchased ahead of proven need, and the corrected configuration that defers it.

Non-compliant configuration: reservation purchased without a usage baseline

resource "google_bigquery_reservation" "analytics" {
  name          = "analytics-reservation"
  location      = "US"
  slot_capacity = 500
  edition       = "ENTERPRISE"
}

resource "google_bigquery_reservation_assignment" "analytics" {
  reservation = google_bigquery_reservation.analytics.id
  assignee    = "projects/${var.project_id}"
  job_type    = "QUERY"
}
resource "google_bigquery_reservation" "analytics" {
  name          = "analytics-reservation"
  location      = "US"
  slot_capacity = 500
  edition       = "ENTERPRISE"
}

resource "google_bigquery_reservation_assignment" "analytics" {
  reservation = google_bigquery_reservation.analytics.id
  assignee    = "projects/${var.project_id}"
  job_type    = "QUERY"
}
resource "google_bigquery_reservation" "analytics" {
  name          = "analytics-reservation"
  location      = "US"
  slot_capacity = 500
  edition       = "ENTERPRISE"
}

resource "google_bigquery_reservation_assignment" "analytics" {
  reservation = google_bigquery_reservation.analytics.id
  assignee    = "projects/${var.project_id}"
  job_type    = "QUERY"
}

This commits 500 slots that bill continuously, whether the analytics project runs one query that day or one thousand. This is a common source of wasted spend on newly launched workloads.

Compliant configuration: on-demand pricing by default

# No google_bigquery_reservation or google_bigquery_reservation_assignment
# resource for this project. Queries run under BigQuery's default
# on-demand pricing, billed per query based on bytes scanned

# No google_bigquery_reservation or google_bigquery_reservation_assignment
# resource for this project. Queries run under BigQuery's default
# on-demand pricing, billed per query based on bytes scanned

# No google_bigquery_reservation or google_bigquery_reservation_assignment
# resource for this project. Queries run under BigQuery's default
# on-demand pricing, billed per query based on bytes scanned

Removing the reservation and assignment resources is non-destructive. It does not affect any underlying data or table, only how future queries are billed.

Step-by-Step Fix Instructions

  1. List every google_bigquery_reservation resource in Terraform state and identify which projects are assigned to each via google_bigquery_reservation_assignment.

  2. Pull slot utilization for each reservation over the past 30 days using BigQuery's slot estimator in the Cloud Console.

  3. If utilization is low, sporadic, or the workload hasn't launched yet, remove the google_bigquery_reservation and google_bigquery_reservation_assignment resources.

  4. Run terraform plan to confirm the removal is non-destructive.

  5. Apply the change and confirm in the Cloud Console, under BigQuery > Administration > Capacity management, that the project no longer has an active assignment.

  6. Add Infracost to CI/CD so any future google_bigquery_reservation resource added to a pull request gets flagged for review before merge.

Best Practices

  • Default new BigQuery workloads to on-demand pricing in shared Terraform modules. Require a documented utilization baseline before a reservation is added.

  • Size any eventual reservation to observed baseline demand, not peak load. Use the autoscale block with a max_slotsceiling to absorb bursts instead of raising slot_capacity outright.

  • Review existing reservations on a recurring basis using slot utilization data, not assumptions about growth.

  • This policy does not apply to workloads with proven, continuous slot demand. Reservations exist because sustained heavy usage really can be cheaper under commitment pricing than on-demand.

Tools and Scripts

Infracost supports this policy check in its free trial and paid plans. When Infracost runs in CI/CD, it evaluates google_bigquery_reservation resources introduced or modified in a pull request and surfaces the finding as a warning in the PR comment before the code merges, giving the team a chance to confirm the reservation is justified before it goes live.

This gives platform teams a pre-purchase signal instead of discovering an oversized commitment on next month's bill. Infracost enables teams to track how many reservations are added against policy over time, which supports burning down this category of waste incrementally and reporting progress to engineering leadership.

To check current reservations and assignments using the gcloud CLI:

bq ls --reservation --project_id=<project-id> --location=US
bq ls --reservation_assignment --project_id=<project-id> --location

bq ls --reservation --project_id=<project-id> --location=US
bq ls --reservation_assignment --project_id=<project-id> --location

bq ls --reservation --project_id=<project-id> --location=US
bq ls --reservation_assignment --project_id=<project-id> --location

Examples of Impact

Illustrative example: provisioning ahead of adoption. A platform team adds a 500-slot BigQuery reservation ahead of launching a new analytics dashboard, expecting fast adoption. Adoption ramps slowly over the following months. The reservation bills for 500 slots the entire time, whether five queries or five thousand run on a given day. Removing the reservation and returning to on-demand pricing until usage stabilizes would have avoided months of largely idle, continuously billed capacity.

Illustrative example: right-sizing after review. A team running quarterly reporting queries finds that its reservation, originally sized for one busy week per quarter, sits mostly idle the rest of the time. Reverting those workloads to on-demand pricing outside the reporting window, and only reserving capacity during the week it's actually needed, removes months of continuous billing for capacity that isn't in use.

(These are illustrative, composite scenarios, not specific customer accounts.)

Considerations and Caveats

  • Minimum commitment size: BigQuery reservations have a 100-slot minimum, purchased in increments of 100. There is no way to reserve a smaller amount.

  • On-demand has a quota too: On-demand pricing includes a slot quota. Google's documentation indicates on-demand customers typically have access to around 2,000 or more slots, which can still be a limiting factor for very high-concurrency workloads.

  • Capacity commitments lock in duration: A capacity commitment, as opposed to a bare reservation, is purchased for a minimum term (monthly or annual) and generally cannot be deleted before that term ends.

  • Query cost only: This policy affects query processing costs. It does not change BigQuery storage costs, which are billed separately regardless of pricing model.

  • Provider-specific: This policy is specific to BigQuery and the google Terraform provider. Other data warehouses have their own commit-versus-on-demand tradeoffs, but the resource and attribute names differ.

Related Policies and Concepts

  • RDS and EMR gp2-to-gp3 storage upgrades: other Compute-group FinOps policies in Infracost's library that reduce cost through a configuration change rather than a usage change, the same underlying discipline this policy applies to slot purchasing decisions.

  • PostgreSQL backup retention in non-production projects: a related Compute-group policy focused on not paying for more resource commitment than a workload actually needs.

  • "How to Enforce Cloud Cost Policies in Your CI/CD Pipeline": a planned Infracost resource article covering the broader workflow of catching cost policy violations like this one at the pull request stage, before they reach production billing.

Frequently Asked Questions (FAQs)

Is this policy supported in Infracost?

Yes. Infracost evaluates google_bigquery_reservation resources in pull requests and surfaces a finding whenever one is added or modified, so the team can confirm it's justified before merge. This check is available in the free trial and all paid plans.

Can this policy be customized?

Yes. Teams can adjust the policy's scope in Infracost, for example limiting the check to specific projects or reservation sizes, rather than relying on the default configuration.

Does Infracost automatically fix violations?

No. Infracost identifies and reports a google_bigquery_reservation resource added in a pull request. Removing the reservation, or waiting for more usage data before keeping it, is a decision the team makes and applies manually.

Is this policy cloud-agnostic?

No. This specific policy targets BigQuery and its Terraform provider (google). Other cloud data warehouses have similar commit-versus-on-demand pricing tradeoffs, but the Terraform resource names and attributes differ.

How often should I review BigQuery reservation sizing?

Teams running Infracost in CI/CD get a check on every pull request that touches a google_bigquery_reservation resource. For reservations already in place, review slot utilization data on a recurring basis, monthly is a reasonable cadence for most teams.

Does switching from a reservation to on-demand pricing affect query performance?

It can. On-demand queries draw from a shared slot pool rather than dedicated capacity, so performance can vary more during periods of high platform-wide demand. This policy recommends evaluating that tradeoff with real utilization data rather than reserving capacity by default.

What is the minimum BigQuery reservation size?

BigQuery reservations have a 100-slot minimum and are purchased in increments of 100 slots. There is no option to reserve fewer than 100 slots.

Create Free Account

This policy is supported in Infracost and available in the free trial. Sign up today and scan your code using our entire library of FinOps policies.

Get started
with Infracost

© 2026 Infracost Inc

Manage cookies

Get started
with Infracost

© 2026 Infracost Inc

Manage cookies

Get started
with Infracost

© 2026 Infracost Inc

Manage cookies