Cloud Run scaling from zero is a feature until it isn't
Scale to zero is a good default for request-driven services, until startup delay, warm-capacity needs, or instance caps turn it into user-visible reliability behavior instead of a pricing feature.
Scale to zero is the right default for a Cloud Run service until startup becomes part of a reliability requirement.
For an internal API used a few times per day, removing idle capacity is an excellent trade. For a latency-sensitive endpoint, the first request after idle may be the user’s entire impression of the system. The same feature now has a product consequence.
Treat warm capacity as a requirement to price, not a failure of serverless purity. Purity remains notably absent from most SLOs.
Measure the path users experience
Cold-start discussions often stop at container startup time. The user waits for the whole path:
- an instance is scheduled
- the image and runtime initialize
- sidecars start
- network connectivity becomes usable
- secrets and configuration load
- database pools establish connections
- application caches warm
- the first request executes
Measure end-to-end latency after the service has genuinely reached zero. Test a new revision as well as an old warm one. A fast framework benchmark says little about a service that spends its first second opening network and database state.
Use startup CPU boost, smaller images, lazy initialization, startup probes, and connection discipline where they address measured delay. Keep initialization deterministic. Then decide whether the remaining cold path fits the user contract.
Minimum instances buy readiness, not immortality
Set minimum instances when predictable response time is worth paying for continuously. Cloud Run keeps a best-effort floor of warm instances, but those instances can still restart, be rebalanced, crash, or temporarily fall below the target.
The application must remain startup-safe. Minimum instances reduce the frequency of cold starts. They don’t remove deployments or infrastructure lifecycle.
Choose the floor from concurrency and availability needs rather than “one feels warm.” A service expected to remain available during an instance restart may need more than one. A low-traffic admin tool may still prefer zero because a slower first response is acceptable.
Separate revision-level and service-level scaling intent carefully during rollouts. Warm capacity assigned to a revision that receives no traffic is capacity doing a very faithful impression of waste.
Scale to zero only applies to the right Cloud Run resource
Cloud Run now exposes several execution shapes. Services can scale from zero in response to traffic. Jobs start for an execution and run to completion. Worker pools and managed instances exist for long-lived non-request workloads and don’t use the same request-driven wake-up model.
Don’t keep a background consumer disguised as an HTTP service merely to inherit autoscaling. Choose the resource whose lifecycle matches the work.
A request-triggered service fits when incoming requests are the demand signal. A queue consumer that must remain connected may fit a worker pool. A finite batch belongs in a job. The question isn’t how to preserve scale-to-zero branding. It’s what should cause compute to exist.
Maximum instances define overload behavior
A maximum instance limit protects cost and finite dependencies such as Postgres. It also limits how much traffic the service can absorb before requests queue, slow down, or fail.
That’s a reliability policy. Set it together with concurrency, client deadlines, retry behavior, and downstream capacity. A max of five with concurrency ten means something different for a CPU-bound endpoint than for requests that each hold a database connection.
Prefer bounded overload to an unlimited fleet attacking the same finite backend. But make the boundary visible. Track pending latency, rejected requests, instance count, concurrency, and dependency saturation. An unexplained slow service isn’t a graceful degradation strategy.
CPU outside requests is a separate decision
Some Cloud Run service workloads need background activity between requests. Instance-based billing and minimum or manual scaling can provide continuously allocated CPU, but the service still retains a request-oriented endpoint and scaling model.
Use that capability for bounded maintenance closely tied to the service. When continuous background processing is the primary workload, a worker pool, job, managed instance, or another runtime is usually a clearer owner.
When scale to zero stops fitting
Keep scale to zero when occasional startup latency is acceptable and requests drive the work. Add minimum instances when measured startup delay violates a real latency or availability target. Move to another Cloud Run resource when the work isn’t request-driven.
Move beyond Cloud Run only when the workload needs a control surface Cloud Run doesn’t provide, not because paying for warm instances feels insufficiently serverless. Warm capacity is often the simplest correct answer.
More in this domain: Infrastructure
Browse allHow we decide between Cloud SQL connectors, Auth Proxy, and private IP
Cloud SQL connectors, the Auth Proxy, and private IP are not interchangeable secure connection options. They change identity, routing, deployment shape, and how much network plumbing the team actually owns.
Safe scaling defaults for Cloud Run + Postgres
Cloud Run autoscaling is not a database strategy. Safe defaults keep the application from scaling itself into a Postgres incident before the team understands the workload.
IAM DB auth for Cloud SQL: when it simplifies security and when it complicates delivery
IAM DB auth can reduce password sprawl and make revocation cleaner, but it also turns database access into an identity operating model that depends on disciplined service-account boundaries.
Cloud Run request timeouts don't kill your code (so your architecture has to)
A Cloud Run request timeout ends the request, not necessarily the work. If the operation can outlive its caller, the system needs explicit job semantics instead of hope.
Direct VPC egress vs Serverless VPC Access for Cloud Run: our default
We default to Direct VPC egress for Cloud Run because it is the cleaner networking shape: fewer moving parts, no connector resource, and costs that scale with the service instead of beside it.
Related patterns
"Internal-only" Cloud Run isn't just a checkbox
Making a Cloud Run service private is not one toggle. It is a decision about ingress, routing, caller path, and IAM working together as one access model.
GKE Autopilot as the escape hatch from Cloud Run
When Cloud Run stops fitting, the next move is usually GKE Autopilot: more Kubernetes-shaped control without immediately taking on the full burden of Standard clusters.
Why we default to Cloud Run for SME internal platforms
For SME internal platforms, Cloud Run is our default because it covers a large share of useful workload shapes without forcing teams to own cluster operations before they have earned that surface area.
How we treat Terraform state in team environments
Terraform starts feeling fragile in teams when state is treated like a backend setting instead of a shared dependency for safe change.