
GCP Committed Use Discounts: Resource vs Spend vs Flex CUDs Explained with Billing SQL | 2026
GCP Committed Use Discounts (CUDs) come in three distinct flavors that are often confused: resource CUDs (lock in specific vCPU/memory at 37–57% off), spend-based CUDs (commit to a dollar amount on Cloud SQL, Memorystore etc. at 25–52% off), and Flex CUDs (commit at region level with the ability to change machine shape at ~20% off). This guide explains each type objectively, covers the discount stacking rules with Sustained Use Discounts, and provides BigQuery billing SQL to measure your actual savings and utilization rate.
By Mateusz Chmielewski · Aug 22, 2026 · 14 min read
What Are GCP Committed Use Discounts?
Committed Use Discounts (CUDs) are contractual discount agreements with Google Cloud where you commit to consuming a specified amount of resources or spend over a 1-year or 3-year term. In exchange for the commitment, Google applies a flat discount to matching usage. CUDs are not reservations — you are committing to pay for a minimum amount, not guaranteeing capacity. There are three distinct commitment types: resource-based CUDs (Compute Engine vCPU/RAM), spend-based CUDs (Cloud SQL, Memorystore, VMware Engine, and select AI services), and Flex CUDs (region-level commitments with machine-type flexibility).
Think of CUDs like a mobile phone contract. A resource CUD is like signing a 1- or 3-year plan for a specific phone model at a discounted monthly rate — cheaper per unit, but you pay whether you use it or not. A Flex CUD is like a plan that lets you upgrade your phone once a year within the same price tier. A spend-based CUD is like pre-buying a data bundle at a wholesale rate — you get a discount on the total spend regardless of exactly how you consume it. Sustained Use Discounts are the pay-as-you-go discount Google gives automatically for using a resource most of the month — but you cannot combine this with a CUD contract.
| Concept | Explanation | When to use |
|---|---|---|
| Resource CUD | Commit to a specific number of vCPUs and GB of RAM in a specific region for 1 or 3 years. Discount: 37% (1yr) or 57% (3yr) vs on-demand. Applies to: Compute Engine, GKE nodes. | Stable, predictable workloads that run >60% of the time with a consistent machine shape — e.g., always-on GKE node pools or production VMs. |
| Spend-Based CUD | Commit to a minimum monthly spend (in USD) on a covered service. Discount: 25% (1yr) or 52% (3yr). Applies to: Cloud SQL, Memorystore, VMware Engine, Vertex AI (select SKUs). | Managed services that cannot be CUD'd by resource — Cloud SQL Enterprise, Cloud SQL Enterprise Plus, Memorystore Redis. |
| Flex CUD | Region-level commitment that allows machine shape changes (vCPU/RAM) within the committed amount without breaking the term. Discount: ~20%. Term: 1 or 3 years. | Variable workloads where you know the total vCPU budget but not the exact machine type — dev/staging environments, experimental services. |
| Sustained Use Discount (SUD) | Automatic incremental discount (up to 30%) for Compute Engine resources that run for more than 25% of the month. Applied by Google without any commitment. | Baseline for any VM — but is REPLACED (not supplemented) by a resource CUD if one applies. |
| CUD Scope — Project vs Shared | By default, CUDs apply to the project that purchased them. Enabling 'shared CUDs' at the billing account level allows a resource CUD in one project to cover matching usage in any project on the same billing account. | Multi-project organizations — always enable shared CUDs to maximize utilization across teams. |
| CUD Utilization Rate | The percentage of your committed capacity that is actually consumed by matching usage. 100% = full discount capture. Below the break-even rate (~60% for 1yr), you pay more than on-demand. | Track monthly in BigQuery billing export — alert if utilization drops below 70%. |
CUDs vs On-Demand vs SUDs — An Objective Comparison
The default GCP billing posture — pay on-demand, hope for Sustained Use Discounts — is the most expensive option for any workload that runs consistently. On-demand pricing provides no guarantee and no discount for stable workloads. SUDs give up to 30% off automatically, but disappear the moment you stop using the resource and cannot be pre-planned. Organizations that skip CUD analysis typically overpay by 25–40% on Compute Engine compared to a well-structured commitment strategy.
A layered CUD strategy covers each resource class: resource CUDs on always-on GKE Autopilot node pools and Cloud SQL (via spend CUD), and Flex CUDs on variable or growing services. The BigQuery billing SQL in this guide (see steps 3–5) provides the data to make this decision before committing. Cross-reference with [GCP Billing Export to BigQuery: Build a Cost Dashboard](/tutorial/gcp-billing-export-bigquery-cost-dashboard-detailed-export-sql) for the full cost visibility setup, and [GKE Autopilot Production Checklist](/tutorial/gke-autopilot-production-checklist-pdb-hpa-vpa-spot-cost) for the Spot VM vs CUD trade-off on burst capacity.
| Feature | thisService | altA | altB |
|---|---|---|---|
| Discount mechanism | Resource CUD: 37–57% off specific vCPU/RAM; Spend CUD: 25–52% off service spend | Sustained Use Discount: up to 30% auto-applied for full-month usage | On-demand: list price, no discount |
| Commitment required | Yes — 1 or 3 year contract; cancellation penalty = remaining committed spend | No — automatic, no contract | No — pay per second/minute |
| Can they stack? | NO — resource CUD replaces SUD on matching usage | NO — SUD is replaced by CUD on matching resources | N/A |
| Flexibility | Resource CUD: shape is locked; Flex CUD: shape can change; Spend CUD: service-level flexibility | Full flexibility — stop any time | Full flexibility |
| Best for | Stable production workloads running >60% of the time | Workloads running 25–80% of the month with variable shape | Ephemeral or unpredictable workloads |
Prerequisites
- GCP project with Billing Account Admin or Billing Account Viewer IAM role
- BigQuery billing export enabled (standard or detailed) — see the sibling guide GCP Billing Export to BigQuery
- gcloud CLI v480.0+ authenticated with billing account access
- At least 30 days of billing export data in BigQuery for meaningful utilization analysis
Step-by-Step Guide
Step 1: Understand the Three CUD Types and Their Discount Mechanics
Before purchasing any CUD, map your resources to the correct commitment type. The three types have different discount rates, applicable services, and scoping rules. Buying the wrong CUD type — e.g., a resource CUD for Cloud SQL (which only supports spend-based CUDs) — results in zero discount application and wasted committed spend.
# Resource CUD — Compute Engine vCPU + RAM (also covers GKE node vCPUs/RAM)
# Discount: 37% (1yr) | 57% (3yr) vs on-demand
# Scope: region-specific, project or shared (billing account)
# Does NOT cover: Cloud SQL, Memorystore, GPUs, local SSDs, preemptible/Spot VMs
# Spend-Based CUD — Cloud SQL, Memorystore, VMware Engine, Vertex AI (select)
# Discount: 25% (1yr) | 52% (3yr) vs on-demand
# Scope: service-level (e.g., all Cloud SQL Enterprise in a region)
# Minimum: $0 minimum spend commitment (can be any amount)
# Flex CUD — Compute Engine (region-level, shape-flexible)
# Discount: ~20% vs on-demand (less than resource CUD)
# Scope: region-level; can change machine type within the commitment
# Does NOT replace resource CUDs — purchased separately
# Check existing commitments:
gcloud compute commitments list --project=PROJECT_ID
# List available CUD plans for a region:
gcloud compute commitments describe --region=europe-west1 --project=PROJECT_ID
Step 2: Calculate Your Break-Even Utilization Rate
The break-even utilization rate is the minimum average usage required for a CUD to save money versus the equivalent on-demand or SUD billing. If your workload averages below the break-even rate, a CUD costs more than on-demand. The break-even is approximately 60–65% for a 1-year resource CUD when compared to on-demand, and lower compared to SUD.
# Break-even formula for Resource CUD:
# Break-even utilization = (On-demand cost) / (CUD committed cost per unit)
# where CUD committed cost per unit = on-demand × (1 - discount_rate)
# Example: n2-standard-4 in europe-west1
# On-demand: $0.2088/hr (4 vCPU × $0.0522/vCPU/hr)
# 1yr CUD: $0.1315/hr committed (37% off) — you pay this even at 0% usage
# SUD max: $0.1462/hr (30% off, only if 100% utilized)
# Break-even vs SUD:
# At X% utilization:
# CUD cost = $0.1315/hr (flat, committed)
# On-demand with SUD = $0.2088/hr × X × (1 - SUD_rate(X))
# Solve for X: break-even ≈ 63% for 1yr vs SUD
# Quick reference table:
# Utilization | On-demand | SUD | 1yr CUD | 3yr CUD
# 100% | $0.2088 | $0.1462 | $0.1315 | $0.0898
# 80% | $0.1670 | $0.1250 | $0.1315 | $0.0898
# 63% | $0.1315 | $0.1315 | $0.1315 | $0.0898 <- CUD/SUD break-even
# 50% | $0.1044 | $0.1044 | $0.1315 | $0.0898 <- below break-even!
# 30% | $0.0626 | $0.0626 | $0.1315 | $0.0898 <- CUD much worse
Step 3: Enable Billing Export and Query CUD Utilization in BigQuery
Enable detailed billing export to BigQuery and run the CUD utilization SQL to see how much of your committed capacity is being consumed and how much discount you are actually capturing. Without the BigQuery billing export, GCP's console shows commitment status but not the actual utilization rate or uncaptured discount opportunity — you are flying blind on whether your commitment is paying off.
-- CUD Utilization Report: actual usage vs commitment (last 90 days)
-- Replace YOUR_BILLING_DATASET with your billing export dataset
SELECT
DATE_TRUNC(usage_start_time, MONTH) AS billing_month,
project.id AS project_id,
sku.description AS sku_description,
SUM(usage.amount) AS total_usage_amount,
usage.unit AS usage_unit,
SUM(cost) AS total_cost,
SUM(
COALESCE((SELECT SUM(c.amount)
FROM UNNEST(credits) AS c
WHERE c.type = 'COMMITTED_USAGE_DISCOUNT'), 0)
) AS cud_credit_amount,
ROUND(
SAFE_DIVIDE(
ABS(SUM(COALESCE((SELECT SUM(c.amount) FROM UNNEST(credits) c
WHERE c.type = 'COMMITTED_USAGE_DISCOUNT'), 0))),
SUM(cost)
) * 100, 2
) AS cud_discount_pct
FROM `YOUR_BILLING_DATASET.gcp_billing_export_v1_*`
WHERE
DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
AND service.description IN ('Compute Engine', 'Cloud SQL', 'Cloud Memorystore')
GROUP BY 1, 2, 3, 5
HAVING SUM(cost) > 0
ORDER BY cud_credit_amount ASC
Step 4: Identify Uncaptured Discount Opportunity
Run a second query to identify on-demand Compute Engine spend that is NOT covered by any CUD — this is your potential savings opportunity if utilization is sufficiently stable. Google applies CUDs to matching usage automatically, but only up to the committed amount. Usage beyond the commitment reverts to on-demand pricing. This query finds the on-demand overhang.
-- Uncaptured CUD Opportunity: on-demand Compute Engine spend with no CUD credit
SELECT
DATE_TRUNC(usage_start_time, MONTH) AS billing_month,
project.id AS project_id,
location.region AS region,
sku.description AS sku,
SUM(cost) AS on_demand_cost,
-- Estimate potential savings at 37% (1yr CUD)
ROUND(SUM(cost) * 0.37, 2) AS potential_1yr_saving,
-- Estimate potential savings at 57% (3yr CUD)
ROUND(SUM(cost) * 0.57, 2) AS potential_3yr_saving
FROM `YOUR_BILLING_DATASET.gcp_billing_export_v1_*`
WHERE
DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
AND service.description = 'Compute Engine'
AND sku.description LIKE '%Instance Core%'
-- Only rows with zero CUD credit applied
AND NOT EXISTS (
SELECT 1 FROM UNNEST(credits) AS c
WHERE c.type = 'COMMITTED_USAGE_DISCOUNT'
)
GROUP BY 1, 2, 3, 4
HAVING SUM(cost) > 50 -- filter noise below $50
ORDER BY on_demand_cost DESC
Step 5: Purchase a Resource CUD with gcloud
Purchase a 1-year resource CUD for Compute Engine vCPU and memory in a target region. Enable shared CUDs at the billing account level to maximize utilization across projects. CUDs purchased at the project level are stranded if that project's usage drops below the commitment. Shared CUDs allow the discount to apply to any project on the billing account — critical for multi-project organizations.
# Step 1: Enable shared CUDs at billing account level (do once)
# In GCP Console: Billing → Commitments → Enable CUD sharing
# Step 2: Purchase a 1-year resource CUD for N2 vCPUs in europe-west1
gcloud compute commitments create prod-gke-n2-1yr \
--plan=TWELVE_MONTH \
--region=europe-west1 \
--resources=vcpu=32,memory=131072MB \
--project=PROJECT_ID
# Explanation:
# vcpu=32 → committing 32 vCPUs (matches 8x n2-standard-4 node pool)
# memory=131072MB → 128 GB RAM (32 vCPUs × 4 GB/vCPU for n2-standard-4)
# Plan: TWELVE_MONTH (1yr, 37% discount) or THIRTY_SIX_MONTH (3yr, 57%)
# Verify the commitment was created:
gcloud compute commitments describe prod-gke-n2-1yr \
--region=europe-west1 \
--project=PROJECT_ID \
--format='yaml(status,plan,endTime,resources)'
Step 6: Purchase a Spend-Based CUD for Cloud SQL
Purchase a spend-based CUD for Cloud SQL Enterprise at the region level. Spend CUDs are purchased in USD minimum monthly spend, not resource units. Cloud SQL cannot be CUD'd with resource commitments — the only discount mechanism beyond standard billing is a spend-based CUD. For a db-custom-4-16384 instance at ~$270/month, a 1yr spend CUD saves ~$67/month ($810/year).
# Spend-based CUDs are purchased via the GCP Console or via REST API
# gcloud does not have a direct CLI command for spend-based CUDs as of Aug 2026
# Console path:
# Billing → Commitments → Purchase commitment
# Service: Cloud SQL
# Region: europe-west1
# Plan: 1 year (25% off) or 3 years (52% off)
# Commitment amount: $270/month (match your current Cloud SQL spend)
# Verify with BigQuery — spend CUD credits appear as type COMMITTED_USAGE_DISCOUNT_DOLLAR_BASE
SELECT
DATE_TRUNC(usage_start_time, MONTH) AS billing_month,
service.description AS service,
SUM(
COALESCE((SELECT SUM(c.amount) FROM UNNEST(credits) c
WHERE c.type = 'COMMITTED_USAGE_DISCOUNT_DOLLAR_BASE'), 0)
) AS spend_cud_credit
FROM `YOUR_BILLING_DATASET.gcp_billing_export_v1_*`
WHERE
DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
AND service.description = 'Cloud SQL'
GROUP BY 1, 2
Step 7: Monitor CUD ROI with a Monthly BigQuery Scheduled Query
Create a BigQuery scheduled query that runs on the 1st of each month and writes CUD ROI metrics to a summary table for dashboarding and alerting. A CUD that was profitable at purchase can become unprofitable if the workload is rightsized, migrated to Spot VMs, or reduced. Monthly automated monitoring catches utilization drops before they compound into months of overpayment.
-- Monthly CUD ROI Summary — schedule this to run on the 1st of each month
-- Write results to: YOUR_DATASET.cud_roi_monthly
SELECT
DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH) AS report_month,
project.id AS project_id,
location.region AS region,
service.description AS service,
SUM(cost) AS gross_cost,
ABS(SUM(
COALESCE((SELECT SUM(c.amount) FROM UNNEST(credits) c
WHERE c.type IN (
'COMMITTED_USAGE_DISCOUNT',
'COMMITTED_USAGE_DISCOUNT_DOLLAR_BASE'
)), 0)
)) AS total_cud_savings,
ROUND(ABS(SUM(
COALESCE((SELECT SUM(c.amount) FROM UNNEST(credits) c
WHERE c.type IN (
'COMMITTED_USAGE_DISCOUNT',
'COMMITTED_USAGE_DISCOUNT_DOLLAR_BASE'
)), 0)
)) / NULLIF(SUM(cost), 0) * 100, 1) AS effective_discount_pct
FROM `YOUR_BILLING_DATASET.gcp_billing_export_v1_*`
WHERE
DATE(usage_start_time) >= DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH)
AND DATE(usage_start_time) < DATE_TRUNC(CURRENT_DATE(), MONTH)
GROUP BY 1, 2, 3, 4
HAVING SUM(cost) > 10
ORDER BY total_cud_savings DESC
Verification & Health Check
Best Practices
- Size CUDs to Minimum Sustained Load, Not Peak or Average
- Always Enable Shared CUDs Across the Billing Account
- Never CUD Spot/Preemptible or Variable Workloads
Common Mistakes
- {"errorCode":"CUD_WASTE — utilization below break-even","symptoms":"Monthly CUD ROI query shows effective_discount_pct below 15%. Actual monthly cost is higher than it would have been with pure on-demand + SUD billing.","rootCause":"Workload was migrated to Spot VMs, rightsized to a smaller machine type, or moved to a different region after the CUD was purchased. The CUD still charges for committed resources even if matching usage dropped.","fixCommand":"gcloud compute commitments describe <NAME> --region=europe-west1 -- check endTime to know when the commitment expires","code":"-- Find underutilized CUDs: compute committed cost vs actual usage cost\nSELECT\n DATE_TRUNC(usage_start_time, MONTH) AS month,\n project.id,\n SUM(CASE WHEN ARRAY_LENGTH(credits) = 0 THEN cost ELSE 0 END) AS on_demand_cost,\n ABS(SUM(COALESCE(\n (SELECT SUM(c.amount) FROM UNNEST(credits) c\n WHERE c.type = 'COMMITTED_USAGE_DISCOUNT'), 0\n ))) AS cud_credit_received\nFROM `YOUR_DATASET.gcp_billing_export_v1_*`\nWHERE DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)\n AND service.description = 'Compute Engine'\nGROUP BY 1, 2\nORDER BY cud_credit_received ASC\n","language":"sql","filename":"underutilized-cud.sql","prevention":"Review CUD utilization monthly. If a workload is moving to Spot VMs or a different region, model the CUD impact first and wait for commitment expiry before changing the architecture."}
- {"errorCode":"COMMITMENT_SHAPE_MISMATCH","symptoms":"CUD was purchased for N2 vCPUs but the node pool was migrated to C3 machine series. CUD credit is not being applied — the billing export shows the C3 usage as on-demand.","rootCause":"Resource CUDs are machine-family specific. An N2 commitment does not cover C3, E2, or other machine families. This is a common trap when upgrading GKE node pool machine types.","fixCommand":"gcloud compute commitments list --region=europe-west1 -- verify machine_type field matches current node pool","code":"# N2 CUD → only applies to n2 and n2d machine types\n# C3 CUD → only applies to c3 machine types\n# If you migrate from n2 to c3, you need a new C3 CUD\n# The old N2 CUD continues to charge until expiry with no discount applied\n\n# Purchase correct C3 CUD for migrated workload:\ngcloud compute commitments create prod-gke-c3-1yr \\\n --plan=TWELVE_MONTH \\\n --region=europe-west1 \\\n --type=MEMORY_OPTIMIZED_ACCELERATOR_OPTIMIZED \\\n --resources=vcpu=32,memory=131072MB\n","language":"bash","filename":"cud-shape-fix.sh","prevention":"Before migrating node pools to a new machine family, check for active CUDs on the old family. Plan the migration to coincide with CUD expiry or purchase a parallel Flex CUD for the new family."}
Cost Analysis
| Feature | metric | cost1k | cost10k | cost100k | cost1m |
|---|---|---|---|---|---|
| On-demand (100% utilization, no commitment) | $0.21/hr | $151.70/mo | $1,820/yr | Baseline | |
| Sustained Use Discount (100% utilization, auto-applied ~30%) | $0.147/hr | $106.2/mo | $1,274/yr | -30% vs on-demand | |
| 1-Year Resource CUD (100% utilization, 37% off) | $0.132/hr | $95.5/mo | $1,146/yr | -37% vs on-demand | |
| 3-Year Resource CUD (100% utilization, 57% off) | $0.090/hr | $65.2/mo | $782/yr | -57% vs on-demand | |
| 1-Year Resource CUD at 63% utilization (break-even vs SUD) | $0.132/hr | $95.5/mo | $1,146/yr | Equal to SUD at 100% | |
| Cloud SQL Spend CUD (1yr, 25% off $270/mo) | $202/mo | $202/mo | $2,424/yr | -$810/yr saved |