HomeWorkGKE → Cloud Run
Case Study - FinOps

Cutting a GCP bill 60% by moving off GKE to Cloud Run

A mixed stateless and batch workload was parked on Google Kubernetes Engine with autoscaling turned on - and a cluster that never came close to saturating it. We relocated the workload to Cloud Run, retired the cluster, and cut the total GCP bill, not just the compute line, by 60% in 2 weeks.

Impact-60%total GCP bill
Timeline2 weeksdiscovery + migration + handover
FinOps stageWalk → Runmaturity shift
CloudGCPSaaS / Data Platform
GKECloud RunCloud BuildTerraformGCP

This is the story of a workload that was paying for an orchestra and only ever seating a quartet. The client ran a mix of stateless services and batch jobs on Google Kubernetes Engine. Autoscaling was on. The cluster was sized for peaks that never arrived. The bill reflected the gap.

The problem: a cluster that paid for its own headroom

GKE is the right tool when you need a control plane, declarative scheduling, and a fleet of services that genuinely fill a cluster. This workload did not. It was a mix of:

  • Stateless services that responded to HTTP traffic - low, bursty, and idle for long stretches.
  • Batch jobs that ran on a schedule, did their work, and then sat doing nothing until the next run.

The team had done the textbook thing: turned on autoscaling, set node pools, configured HPA. The problem is that autoscaling closes the gap after it opens. On GKE you still pay for the control plane, the minimum node footprint, and the lag between a scale event and a node being ready. For a workload that was idle more often than it was busy, that lag was the entire cost story. The cluster was effectively paying to be ready for a peak that lived in a spreadsheet, not in production.

The result showed up clearly in the monthly bill: the GKE line item was the dominant cost, and it barely moved month over month - the signature of a workload being charged for capacity rather than consumption.

The diagnosis: capacity pricing vs. consumption pricing

The first thing we did was separate the two workloads in the cost data. Stateless services and batch jobs have completely different cost profiles, and lumping them onto one cluster hides both. Once we isolated them, the picture was unambiguous:

  • Stateless services were paying for 24/7 node capacity to serve traffic that was bursty and intermittent. A consumption-based platform would charge them only for the requests they actually served.
  • Batch jobs were paying for nodes that sat idle between runs. A job-based platform would charge them only for the seconds the job actually ran.

Both workloads had the same root cause, and it was not a GKE misconfiguration - it was a platform mismatch. GKE charges you for capacity. Cloud Run charges you for requests and execution time. When your workload is idle more than it is busy, that difference is the entire bill.

The move: relocate, don't rebuild

The goal was not to re-architect the application. The services were already containerized - that is what made this a relocation rather than a rewrite. The work was in the scaffolding around the containers, not the containers themselves.

What we actually did

  • Re-platformed the stateless services to Cloud Run.Same containers, different execution model. Cloud Run's request-based billing meant the services now cost roughly zero when no one was calling them - and scaled to zero automatically, with a cold-start profile that was acceptable for this traffic pattern.
  • Re-platformed the batch jobs to Cloud Run Jobs.Each job became a Cloud Run Job that executed, finished, and stopped costing money. No more paying for a node between scheduled runs.
  • Rebuilt the delivery pipeline in Terraform.Every Cloud Run service and job was provisioned declaratively - no clicking in the console, no snowflake configs. The same Terraform could spin up a mirror environment for testing, which is what made the cutover low-risk.
  • Wired up Cloud Build for CI/CD.Push to the repo, Cloud Build builds the image, Cloud Run deploys it. The team kept their existing git workflow - only the deploy target changed.
  • Retired the GKE cluster.Once traffic and jobs were verified on Cloud Run, the cluster was decommissioned. This is where the bulk of the savings landed - the control plane fee, the node pools, and the idle capacity all stopped billing at once.

The result: 60% off the total bill, not just compute

The headline number is 60% off the total GCP bill, which is the only number that matters. Compute-only savings are easy to manufacture; total-bill savings are what shows up in finance. The reduction held because it was structural - the workload was no longer paying for capacity it did not use, and there was no way for the old cost pattern to creep back in as long as the workload stayed on a consumption-based platform.

The whole engagement - discovery, migration, and handover - took 2 weeks. The speed was possible because the decision was clean: the workload was already containerized, the target platform was consumption-based, and the Terraform factory meant we could stand up the new environment without touching the application code.

Why this is a FinOps maturity story, not just a migration

This is the part that connects to the broader FinOps conversation. Before this engagement, the client was at what we'd call the Walk stage of FinOps maturity: they had visibility into costs, they had tried optimization (autoscaling), but they were still optimizing within a fixed platform choice. They were tuning the dials on a platform that was structurally wrong for the workload.

The move to Cloud Run shifted them to Run: the cost model now matches the workload's actual shape, the platform itself does the optimization (scale to zero, per-request billing), and the team's attention is free for higher-value work. That is the difference between cost optimization and cost structure - and it is the same idea we lay out in more depth in ourFinOps maturity framework.

The lesson generalizes. The biggest cost wins rarely come from tuning the platform you are on. They come from honestly asking whether the platform matches the workload - and being willing to relocate when it does not.

Engagement shape

  • Duration: 2 weeks, end to end (discovery + migration + handover).
  • Scope: discovery, migration, Terraform factory, CI/CD, handover.
  • Risk profile: low - workloads were containerized, cutover was staged and reversible.
  • Outcome: -60% on the total GCP bill, sustained, with a platform that scales to zero.

Published: 2026-08-03 - Alveon

Ready to make your cloud perform?

Book a 30-minute architecture review. We'll pressure-test your setup and show you exactly where the next 10% lives - no commitment.