2026-03-25 · GCP Cost
Why Did My Google Cloud Bill Spike?
Google Cloud billing is genuinely harder to diagnose than AWS or Azure for one reason: the native Cost Table in the console gives you summary views, but getting to the actual root cause almost always requires the BigQuery billing export. If you have not set that up, tracking down a spike means clicking through incomplete summaries.
Here are the most common causes of GCP bill spikes, how to check each one, and how to fix it.
1. Committed Use Discounts Expired
GCP offers Committed Use Discounts (CUDs) for Compute Engine, Cloud SQL, and some other services. You commit to a certain amount of compute capacity for one or three years and receive a significant discount in return. When the commitment ends, your workloads fall back to on-demand pricing immediately, no warning, no grace period.
The gap is material. An n2-standard-32 instance in us-central1 costs around $1,550/month on-demand. With a one-year resource-based CUD, that drops to roughly $1,100/month, about 30 percent off. For memory-optimized instances like m2-ultramem, the CUD discount can be even larger. A commitment covering several of those instances expiring simultaneously is a large and sudden cost increase.
**How to check:** Go to the GCP console, navigate to Billing, then Commitments. You can see all active and expired commitments along with their expiration dates. You can also filter your billing export by credit type, rows with credits.type = COMMITTED_USAGE_DISCOUNT show where CUDs are being applied. A drop in credit volume on those rows signals an expiration.
**How to fix:** Purchase new CUDs to cover the affected vCPUs and memory. If your workload varies, a spend-based CUD is more flexible than a resource-based one. If the workload is shrinking or uncertain, evaluate whether on-demand pricing is acceptable short-term while you plan the next commitment.
2. Sustained Use Discounts Changed
Sustained Use Discounts (SUDs) are automatic discounts GCP applies to Compute Engine VMs that run for a significant portion of the month. The discount scales up to about 30 percent for resources that run the entire month. You do not have to do anything to get them, GCP applies them automatically.
The problem is that SUDs are calculated on vCPU and memory aggregated across the month, not per individual instance. If you replace a small number of long-running instances with a larger number of shorter-lived instances, for example, switching from always-on VMs to spot instances with frequent restarts, your effective SUD percentage drops and your bill increases even if total compute hours stayed roughly constant.
**How to check:** In the Billing export in BigQuery, query your credits array filtered to type = SUSTAINED_USE_DISCOUNT and compare the total credit value month over month. If the credit amount dropped, your effective run-time percentage decreased. Cross-reference with your Compute Engine usage to see if average instance uptime changed.
**How to fix:** If the SUD drop is intentional because you switched to spot instances, the tradeoff is expected. If it is accidental, review your instance lifecycle. Keeping core workloads on persistent VMs that run the full month maximizes SUD benefit. Spot instances are better suited for batch workloads where interruption is acceptable.
3. BigQuery On-Demand Queries Scanned Too Much Data
BigQuery offers two pricing models. Capacity pricing charges for reserved processing slots regardless of queries run. On-demand pricing charges $6.25 per TB scanned. For most teams that have not committed to flat-rate slots, on-demand is the default.
On-demand queries are one of the most common sources of unexpected GCP spikes. A single poorly-written query scanning an unpartitioned 10 TB table costs $62.50, per run. If a batch job starts running that query hourly instead of nightly, the monthly cost jumps from $1,875 to $45,000 for that query alone. SELECT * on a large table, forgetting a WHERE clause on a partitioned column, or a JOIN that causes a table scan instead of using clustered fields are all common triggers.
**How to check:** Go to BigQuery and open the Job History for the affected project. Click into expensive-looking jobs and check the bytes billed column. For a systematic view, query INFORMATION_SCHEMA.JOBS_BY_PROJECT:
``sql
SELECT
user_email,
query,
total_bytes_billed,
total_bytes_billed / POW(1024, 4) * 6.25 AS estimated_cost_usd,
creation_time
FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE creation_time BETWEEN TIMESTAMP('2026-03-01') AND TIMESTAMP('2026-04-01')
ORDER BY total_bytes_billed DESC
LIMIT 20;
``
**How to fix:** Add partition filters to queries that scan partitioned tables. Use clustering to allow BigQuery to prune data before scanning. Set a per-project or per-user byte quota in BigQuery IAM settings to cap the damage from runaway queries. Consider switching to flat-rate slots if query volume is predictable and large enough to make it cheaper.
4. Cloud Storage Egress or Operations Charges Jumped
GCP charges for data leaving Cloud Storage to the internet or to other regions. Inbound and within-region transfers are free. Outbound to the internet from North America costs $0.12/GB for the first 10 TB per month. Outbound between GCP regions costs $0.01 to $0.08/GB depending on destination.
Operations charges can also catch teams off guard. Cloud Storage charges per operation: $0.05 per 10,000 Class A operations (writes, lists) and $0.004 per 10,000 Class B operations (reads). A data pipeline that begins making frequent LIST calls or a process that writes many small objects will generate significant operations charges even if total storage capacity barely changed.
**How to check:** In the GCP console, go to Storage > Monitoring for the bucket and check the request count metric grouped by method. Compare request volume week-over-week. In the BigQuery billing export, filter by service.description = 'Cloud Storage' and group by sku.description to separate capacity, egress, and operations charges. The SKU names make it clear which component increased.
**How to fix:** For operations: batch small writes into fewer, larger objects. Avoid frequent LIST operations on large buckets, use object naming conventions that let your application construct paths directly. For egress: verify that services consuming data from Cloud Storage are in the same region as the bucket. Route through a CDN for public-facing assets to avoid per-GB egress charges on repeated downloads.
5. Pub/Sub or Cloud Functions Message Volume Increased
GCP Pub/Sub charges per GB of data published and delivered. The first 10 GB per month in each region is free, then $0.04/GB for publisher throughput and $0.04/GB for subscriber throughput. A message delivery failure that causes a retry loop can rapidly multiply your effective message volume.
Cloud Functions charges for invocations ($0.40 per million beyond the free tier) and for GB-seconds of compute. A function triggered by Pub/Sub messages or Eventarc events that starts running at ten times its normal rate, because an upstream service started sending more events, or because a dead-letter queue started replaying messages, will show both Pub/Sub and Cloud Functions costs increasing together.
**How to check:** Go to Pub/Sub in the console and check the Subscription Metrics for each subscription. Look at the Undelivered message count and the Oldest unacked message age. A growing backlog means messages are not being processed fast enough, which can trigger retries. In Cloud Functions, check the invocation count metric in Cloud Monitoring and compare against the prior month.
**How to fix:** Add dead-letter topic limits to subscriptions to cap the number of redelivery attempts before a message is dropped. Set a maximum delivery attempt count appropriate for your use case. For Cloud Functions with unexpectedly high invocation counts, add logging to identify the triggering event source and trace it back to the upstream cause.
6. GKE Cluster Fees or Node Scaling
GKE charges a cluster management fee of $0.10 per hour for each cluster beyond the first one in a project. That is roughly $72 per month per cluster. Teams that create clusters for individual features, experiments, or short-term tests and leave them running can accumulate several hundred dollars per month in management fees alone.
GKE also charges for the underlying Compute Engine VMs in each node pool. Cluster autoscaler scaling events that add nodes and do not scale them back generate persistent VM charges. Autopilot clusters bill per pod resource request rather than per node, which avoids idle node waste, but can still surprise you if workloads scale unexpectedly or if resource requests are set much higher than actual consumption.
**How to check:** List all GKE clusters in your organization using gcloud container clusters list --all-projects. Any cluster you cannot immediately explain is a candidate for review. Check node counts in the GKE console for each cluster and compare against what the workload actually requires. In the billing export, filter by service.description = 'Kubernetes Engine' and group by resource.labels.cluster_name to see the cost per cluster.
**How to fix:** Delete clusters that are no longer needed. For non-production clusters, set a scheduled node pool scale-down at end of day. Review autoscaler configuration, specifically the maximum node count and scale-down utilization threshold. For Autopilot clusters, right-size pod resource requests to match actual consumption.
How to Find the Root Cause Step by Step
Start in the GCP console under Billing > Cost Table. Set the date range to cover both months and group by Service. Sort by the largest absolute increase. This tells you which service changed.
Once you have the service, the most reliable next step is the BigQuery billing export. Run a query grouping by service.description, sku.description, and month:
``sql
SELECT
FORMAT_TIMESTAMP('%Y-%m', usage_start_time) AS month,
service.description AS service,
sku.description AS sku,
SUM(cost) AS total_cost
FROM your-project.your_dataset.gcp_billing_export_v1_*
WHERE usage_start_time >= TIMESTAMP('2026-02-01')
GROUP BY 1, 2, 3
ORDER BY total_cost DESC;
``
The SKU description in GCP billing is equivalent to the Meter in Azure or the usage type in AWS. It tells you exactly what category of charge drove the increase: if the service is Compute Engine and the SKU is N2 Instance Core running in Americas, you know it is Compute Engine vCPUs in a US region running more hours or at a higher rate than before.
For volume versus price analysis, compare the usage.amount and cost / usage.amount across periods for the same SKU. If usage went up and unit cost stayed flat, it is a volume problem. If usage is flat but unit cost increased, a discount (CUD or SUD) was reduced or expired.
If you have not set up the BigQuery billing export, go to Billing > Billing Export in the console and enable it now. It takes about 24 hours to start populating. Without it, GCP cost investigation is significantly harder.
How to Prevent Future Spikes
Set Budget Alerts in GCP Billing at 50, 80, and 100 percent of your expected monthly spend. Add a forecasted spend alert as well, GCP can alert you when the month-end forecast exceeds your budget before the billing period ends.
Track CUD expirations in your team calendar at 60 and 30 days out. GCP does not send renewal reminders by default. The Commitments page in Billing shows expiration dates, but only if you go looking.
Enable the Recommender API for Committed Use Discount recommendations. GCP analyzes your usage patterns and tells you which CUDs would save the most money, reducing the guesswork on what to commit to.
Set BigQuery byte quotas for projects running on-demand queries. A per-project daily limit caps the maximum damage from a runaway query before it hits your invoice.
Bottom Line
Most GCP bill spikes trace to one of three things: a commitment discount expired, something scaled up and was not scaled back, or a query or job started processing far more data than intended. BigQuery on-demand query costs are the GCP-specific risk that has no real AWS or Azure equivalent, a single bad query in the wrong place can generate a large one-time charge.
The BigQuery billing export is the most important tool you can have for investigating these. If it is not enabled, turn it on today. BillSpike supports GCP FOCUS exports alongside AWS CUR files. The same volume versus price variance analysis it runs on AWS applies directly to GCP billing data when exported in FOCUS format.
Analyze your own AWS cost spike at billspike.io