Skip to main content

Revisions & traffic splitting

Exam guide§2.1

Every deploy - a new image or just a config change - creates a new immutable revision. What makes revision a first-class resource is that you control which revision(s) serve traffic and in what proportion: split for canary/blue-green, pin for rollback, and tag for testing before any traffic flows.

Deploying a revision

Before Cloud Run can run your container, the image must live in a repository Cloud Run can reach - normally a Docker repository in Artifact Registry. You push the image there; Cloud Run pulls it at deploy time.

DeveloperArtifact RegistryCloud RunPush imagePull image
Before a container can run on Cloud Run its image must live in a repository Cloud Run can reach: the developer pushes the image to Artifact Registry, and Cloud Run pulls it from there at deploy time.

Deploy with the console, the gcloud CLI, a YAML config file, or Terraform. You hand Cloud Run a container image URL; it records that in a service configuration and produces a service plus a new revision.

Developergcloud run deploy --image=...Service configurationCloud RunServiceRevisionArtifact RegistryDocker repositoryCreate/Update serviceReferences image URL
A gcloud run deploy (or console) call creates or updates a Service configuration, which Cloud Run turns into a Service plus a new Revision that references the container image URL in Artifact Registry.

The first deploy creates the service and its first revision; every later deploy to that service automatically creates a new revision.

  • A service has exactly one container image at a time - each revision points at one image URL.
  • Changing any service configuration setting creates a new revision too, even with no change to the image. Subsequent revisions inherit the previous config unless you explicitly override it.
GotchaConfig changes make revisions, not just image changes

It is not only a new image that produces a revision. Editing env vars, memory/CPU limits, concurrency, scaling bounds, the service account, or any other setting deploys a new revision. Roll back by shifting traffic to an older revision - the old config is still there, frozen.

GotchaIAM roles needed to deploy

To deploy, you need Owner, Editor, or both the Cloud Run Admin (roles/run.admin) and Service Account User (roles/iam.serviceAccountUser) roles - or a custom role with the equivalent permissions. Cloud Run Admin alone is not enough; you also need Service Account User to let the revision run as its service account.

CommandsDeploy, split, roll back
# Deploy a new revision (first deploy creates the service + first revision)
gcloud run deploy api --image=us-docker.pkg.dev/p/repo/api:v2 \
--region=us-central1 --allow-unauthenticated
 
# Canary: 90% old, 10% new
gcloud run services update-traffic api \
--to-revisions=api-v1=90,api-v2=10
 
# Roll back to a known revision
gcloud run services update-traffic api --to-revisions=api-v1=100

A revision is immutable

Each time you change the service resource, Cloud Run makes an immutable copy of it - the revision. "Immutable" means you can never edit a revision in place; you only ever add new revisions. A revision bundles the container image with its service configuration.

Service resourceCloud RunRevisionOlder revisionsRevisionContainer imageService ConfigurationWatch changesMakes an immutable copy
Every change to the service resource makes Cloud Run stamp out a new immutable revision - a frozen copy of the container image plus its service configuration; you never edit a revision, you only add new ones.

Updating a service

The service resource holds the configuration that describes how Cloud Run runs your application. When you deploy a change to it, Cloud Run watches for the change and rolls out a new revision of your app.

YouService resourceCloud RunYour webappDeploy or change configurationWatch changesDeploy new revisionConfiguration:Container image URL,environment variables,CPU/memory size,scaling boundariesThe service configurationdescribes howCloud Runruns your application.
Updating a service: you deploy a change to the Service resource, Cloud Run watches it and rolls out a new revision of your webapp. The service configuration describes how Cloud Run runs your application.
  • Send all traffic to the new revision as soon as it is healthy, or
  • perform a gradual rollout by controlling the percentage of requests sent to the new revision.

Rolling out a new revision

Cloud Run does not cut traffic over the instant a revision is created. It scales up the new revision first and waits for it to be ready, while the current revision keeps serving:

After a change, Cloud Run creates a new revision.RevisionAdd revision1RevisionsStarting...Serving requestsWait for ready2Latest revisionOlder revisionsContainer instances
Scaling up a new revision: Cloud Run adds the revision, starts one new instance and waits for it to be ready, while the current revision keeps serving all request traffic.

Once the new instances are healthy, Cloud Run routes traffic to the new revision. Both revisions then autoscale independently: the previous revision stops receiving requests, goes idle, and eventually scales to zero; the new revision adds instances as demand requires.

After a change, Cloud Run creates a new revision.RevisionNew revisionRevisionsServing requestsIdleScaled to zero3Traffic is migrated to the new revisionLatest revisionOlder revisionsContainer instances
Step 3, traffic migrated: the new revision is now serving requests while the previous revision goes idle and scales to zero, both autoscaling independently.

For a controlled rollout, deploy with --no-traffic so the new revision receives 0% initially, then raise its percentage incrementally once you have vetted it.

Splitting traffic

Client AClient BAAABBABABhello-xyz-uc.a.run.app10%90%ABAABRevisionRevisionABRequests
Splitting traffic: requests from every client hit one stable run.app URL, then Cloud Run fans them across revisions by the percentages you set - here 10% to the new revision and 90% to the old.

Assign each revision a percentage of requests. This is how you roll back, gradually roll out, or run two revisions side by side.

  • Configure percentages in the console, gcloud, a YAML file, or Terraform.
  • Traffic changes are not instantaneous: when you change the split, in-flight requests run to completion and are never dropped - during the transition a request may land on either the new or the previous revision.
GotchaSession affinity is best-effort

By default, requests from the same client can hit different container instances. Enabling session affinity makes Cloud Run try (best-effort, not guaranteed) to route a client to the same revision's instance. If you split traffic with session affinity on, the effective split can skew - see the docs on session affinity and traffic splitting.

Pinning traffic

Pinning sends 100% of traffic to one specific revision instead of the latest. It decouples deploying a revision from migrating traffic to it: add a new revision and Cloud Run will not automatically send it any traffic.

Requestshello-xyz-uc.a.run.appRevisionRevisionRevisionLatest revisionOlder revisionsIf you pin traffic to a revision, it stays there until you change it.
Pinning traffic: you route 100% of requests to one chosen revision and it stays pinned there - Cloud Run will not shift traffic to newer revisions until you change the pin yourself.

Pin when you want to roll back to a known-good revision, or test a new revision before moving production traffic to it.

Tagging revisions

Requestshello-xyz-uc.a.run.appRevisionTaggreen---hello-xyz-uc.a.run.appRevisionTest URL: https://green---hello-xyz-uc.a.run.app
A tagged revision gets its own test URL - the tag name added as a prefix to the service URL (green---hello-xyz-uc.a.run.app) - so you can reach that revision directly without any production traffic being routed to it.

A tag gives a revision its own URL - the tag name added as a prefix to the service URL (e.g. tag green on service hello becomes https://green---hello-xyz-uc.a.run.app) - without serving it any production traffic.

  • Reach the tagged revision directly to test and vet it; when it is confirmed good, start migrating traffic to it (console, gcloud, YAML, or Terraform).
  • A useful pattern: tag a revision with the commit ID used to build it.

Recap

FactsService configuration - any change = a new revision

The settings captured in a revision (changing any one deploys a new revision):

  • Container image URL
  • Container entrypoint and arguments
  • Secrets and environment variables
  • Request timeout
  • Concurrency (max concurrent requests per instance)
  • CPU / memory limits
  • Scaling boundaries (min / max instances)
  • Google Cloud config (service account, connectors)
DECISIONHow should I move traffic to a new revision?
Ship and take all traffic once healthyNormal deploy (latest revision serves)
Gradual / canary rolloutSplit traffic by percentage (--to-revisions)
Deploy now, migrate traffic laterDeploy with --no-traffic, then raise %
Roll back to a known-good revisionPin 100% to that revision
Test a revision before any real trafficTag it and hit its test URL
Pick this when: match the goal to the traffic control