Cloud Run container lifecycle
A Cloud Run service is the resource you interact with - deploy a new image, roll back to a revision, or change config (env vars, scaling). Each deploy creates an immutable revision; the first deploy creates the service and its first revision. Every service gets a unique, permanent HTTPS endpoint on a run.app subdomain that never changes. To serve a request, Cloud Run starts a container and forwards the request to it.
Deploys, revisions, and traffic splitting are covered on Revisions & traffic splitting. This page is about what happens to a container instance at runtime.
The five states
- Starting - Cloud Run materializes the image and starts your app.
- Serving requests - the container is handling web requests.
- Idle - the container is not handling requests (CPU throttled, no charge).
- Shutting down - if you handle the shutdown hook, you get to stop gracefully.
- Stopped - the container is gone.
Starting
The Starting phase begins when Cloud Run pulls the image and ends when the container starts serving. Four steps:
- Cloud Run creates the root filesystem by materializing the container image.
- It runs the container's entrypoint (your application).
- It probes port 8080 (configurable) to check whether the app is ready.
- Once the app accepts TCP connections, Cloud Run forwards requests to it.
Cloud Run treats "accepts TCP connections" as "ready for traffic." If your app opens the port before it can actually serve, requests hit it too early. Open the port only when you are ready to handle requests - or configure an explicit startup probe.
- Startup and liveness probes support HTTP, TCP, and gRPC, configured via YAML for new and existing services.
- A startup probe determines when a container has started and is ready to accept traffic.
- Default probe target is port 8080.
Where the image comes from
Cloud Run pulls a container image at two distinct moments, from two sources:
- Deploy (first time): Cloud Run pulls and copies the image from Artifact Registry into its own internal storage.
- Start (every new container): Cloud Run pulls the image from internal storage, not Artifact Registry.
Because Cloud Run keeps its own copy, container starts do not depend on Artifact Registry - your service survives an Artifact Registry outage, or even accidentally deleting the deployed image from Artifact Registry. Internal storage is also optimized so large images load as fast as tiny ones.
Idle
A container stays in Serving requests as long as it handles web requests. After 100 ms with no requests it transitions to Idle. An idle container:
- Does not serve requests and does not incur charges.
- Has its CPU throttled to nearly zero - your app runs very slowly.
- Can be shut down at any time (you get a shutdown hook to clean up).
Going Idle → Serving is seamless: on the next request Cloud Run unthrottles the CPU and returns full access immediately, so users see no lag.
With CPU throttled to ~zero, you can't reliably run background tasks, and network requests to third parties are likely to fail while idle. Options: set CPU always allocated (charged for the container's whole lifecycle, useful for short-lived background/async work), or schedule work with Cloud Tasks.
- Idle transition after 100 ms with no requests.
- Cloud Run may keep instances idle for up to 15 minutes to absorb traffic spikes and cut cold starts.
- Set minimum instances to always keep some instances ready to serve.
Shutting down
If a container is idle, Cloud Run can decide to stop it. By default a container just disappears when shut down. To stop gracefully, build your app to handle the SIGTERM signal - it warns the app that shutdown is imminent and gives it 10 seconds to clean up before removal.
Graceful shutdown work worth doing in those 10 seconds:
- Close open TCP connections, file descriptors, and database connections (downstream systems are slow to time out idle connections - under heavy scaling you can hit max-connection errors).
- Flush any buffers of batched data (telemetry, etc.).
- Write a log entry to help debugging later.
Most languages provide libraries to trap termination signals like SIGTERM and run routines before exit.
Stopped
A container reaches Stopped two ways:
- Graceful - it handled SIGTERM, cleaned up within 10 s, then exited.
- Forceful - it did not handle SIGTERM (Cloud Run stops it immediately, process just disappears), or it stopped suddenly.
Cloud Run never stops a container while it serves requests under normal circumstances. But a container can stop suddenly if:
- Your application exits (e.g. a bug in your code), or
- It exceeds the memory limit (default 512 MiB per instance).
If a container stops while handling requests, all in-flight requests are terminated and fail with an error. While Cloud Run starts a replacement, new requests may have to wait.
- Default memory per container instance (service revision or job): 512 MiB.
- Configurable up to 32 GiB.
Recap
- Idle after: 100 ms with no requests.
- Kept idle: up to 15 minutes (cold-start buffer).
- SIGTERM grace period: 10 seconds.
- Default memory: 512 MiB (max 32 GiB).
- Startup probe port: 8080 (default).