Serverless Workers on GCP Cloud Run
This page covers how Serverless Workers work on GCP Cloud Run, including the instance lifecycle, autoscaling behavior, and how Worker Versioning maps to Cloud Run Worker Pools.
On Cloud Run, a Serverless Worker runs in a Worker Pool: a set of long-lived instances that poll the Task Queue continuously for as long as they remain in the pool. Each instance runs standard Worker code and processes Tasks for its whole lifetime. The Worker Controller Instance (WCI) controls how many instances run; each instance manages its own polling and Task processing.
Autoscaling
The WCI keeps the Worker Pool sized to the amount of work arriving on the Task Queue. It combines two mechanisms:
- Immediately bring up new instances when a Task arrives and no Worker is free to take it (a sync match failure).
- Resize the Worker Pool periodically based on incoming work.
The immediate reaction absorbs bursts without waiting on the evaluation cycle. The periodic re-sizing is where the WCI does its rate-based planning.
For that planning, the WCI measures two rates over time:
- How fast Tasks arrive.
- How fast a single Worker processes them.
From these, it calculates how many Workers it takes to handle the incoming work, sets the pool's target instance count accordingly, and adjusts it as the arrival rate changes.
The WCI holds back some spare capacity rather than loading every Worker to 100%. It sizes the pool to a target utilization (80% by default), so there is room to pick up newly arriving Tasks right away instead of queuing them. When Tasks are already waiting in the backlog, the WCI adds more instances on top to work through them faster.
It applies the resulting count to the pool through the Cloud Run admin API, and keeps the count within a minimum and maximum bound.
Scale-out
When arrivals rise or backlog builds, the WCI raises the pool's target instance count and Cloud Run starts more instances. Because the WCI keeps a utilization buffer, the pool adds capacity ahead of demand rather than waiting until Tasks pile up. Since a new instance takes time to start and connect before it can poll for Tasks, provisioning ahead of demand keeps the backlog from growing during that startup window.
Scale-in
When arrivals and backlog fall, the WCI lowers the target instance count and Cloud Run stops surplus instances. Scale-in is more conservative than scale-out. The WCI holds capacity while sync match failures are still occurring, and it applies a cooldown before reducing the pool, so it does not remove instances that are about to be needed again. When there is no work, the WCI can scale the pool to zero; the next sync match failure or backlog scales it back up.
Worker Versioning
Serverless Workers require Worker Versioning. Create one Worker Pool for each Worker Deployment Version, and carry the Build ID in the pool name.
The compute configuration names a project, region, and Worker Pool. It does not name a revision, so Temporal runs whichever revision the pool serves at the time. That ties a pool to one build, and a new build needs a new pool.
Keep an older version's pool in place while Pinned Workflows are still running on it. The pool can sit at zero instances, and its WCI scales it back up when a Task arrives for that version.
Deploying a new image into a pool that a live Worker Deployment Version points at creates a new revision, and Cloud Run promotes it to every instance by default. The version does not change, but the code behind it does. Deploying replay-unsafe code this way causes non-determinism errors for in-flight Workflows, including Pinned ones.
For step-by-step instructions, see Create the Worker Pool.
Lifecycle
A Cloud Run Serverless Worker is an ordinary long-lived Temporal Worker. Each instance runs the same Worker code you would run anywhere else: it connects to Temporal, registers its Workflows and Activities, and polls the Task Queue for its whole lifetime. You do not start or stop instances yourself. Cloud Run runs the containers, and the WCI sets how many run through its scaling operations.
An instance's lifetime is bounded by scale-in. The WCI decides when to remove an instance from Task Queue activity, not from what any individual instance is doing. It waits a set amount of time after the most recent sync match failure, and applies a cooldown between successive reductions, before lowering the target instance count. It does not track how long a given instance has been running or whether that instance is mid-Activity, so the instance Cloud Run stops may be one that is still executing work.
Use Activity Heartbeats so that if an Activity is interrupted, a retry resumes from the last recorded progress instead of restarting from the beginning.