Today, we’re announcing the General Availability of Worker Versioning and a Public Preview of Upgrade on Continue-as-New, a new capability that eliminates patching for many long-running Workflow patterns.
See also: Announcing Worker Versioning Public Preview: Pin Workflows to a single code version
Background: Updating Workflows#
Deploying new code to long-running Workflows has always been one of the trickier problems in Durable Execution. If you change your Workflow logic, you risk breaking Workflows that started execution before the latest Worker Deployment.
So how do you handle Workflows that are already running when you deploy a new version of your Worker code? Prior to Worker Versioning, the traditional answer has been Workflow Patching: conditional branches in your code that check whether a Workflow started before or after a particular change.
Because Temporal Workflows can run for days, weeks, or even years, patches accumulate into real code complexity and cognitive overhead.
How Worker Versioning works#
Worker Versioning takes a different approach. Instead of embedding version logic in your Workflow code, you declare Versioning Behavior at the Workflow type level:
- PINNED: Workflows stay on the Worker version where they started for their entire lifetime
- AUTO_UPGRADE: Workflows automatically move to new Worker Deployment Versions
When you deploy a new Worker version, Temporal routes Workflows according to these rules. Pinned Workflows continue executing on Workers running the old code; Auto-Upgrade Workflows automatically move to the latest version when it becomes available.
For most use cases, that’s enough. But for the longest-running Workflows (such as “entity Workflows” that run for months, or AI agents that sleep for weeks between interactions), neither behavior has offered a clean answer. Until now.
Introducing Upgrade on Continue-as-New#
Many long-running Workflows already use Continue-as-New as natural checkpoints: committing progress, resetting accumulated Event History, or picking up new configuration.
Upgrade on Continue-as-New lets you use these boundaries as version upgrade points:
-
Your Workflow runs pinned to its original version (no patches needed during a run)
-
When a new Worker Deployment Version becomes Current or Ramping, active Workflows can detect this through
target_worker_deployment_version_changed -
At your next Continue-as-New, you can opt into the upgrade
-
The new run starts on the Current or Ramping version
Using Continue-As-New this way, each run can be short enough to complete on a single version, even though the logical Workflow spans many versions over its lifetime. For more detail, see the documentation.
func (w *Workflows) ContinueAsNewWithVersionUpgradeV1(
ctx workflow.Context,
attempt int,
) (string, error) {
if attempt > 0 {
return "v1.0", nil
}
// Check GetTargetWorkerDeploymentVersionChanged periodically.
// GetTargetWorkerDeploymentVersionChanged is refreshed after each WFT completes.
for {
err := workflow.Sleep(ctx, 10*time.Millisecond)
if err != nil {
return "", err
}
info := workflow.GetInfo(ctx)
if info.GetTargetWorkerDeploymentVersionChanged() {
return "", workflow.NewContinueAsNewErrorWithOptions(
ctx,
workflow.ContinueAsNewErrorOptions{
// Pass InitialVersioningBehavior=workflow.ContinueAsNewVersioningBehaviorAutoUpgrade
// to make the new run start with AutoUpgrade behavior and use the Target Version of
// its Worker Deployment.
InitialVersioningBehavior: workflow.ContinueAsNewVersioningBehaviorAutoUpgrade,
},
"ContinueAsNewWithVersionUpgrade",
attempt+1,
)
}
}
}
func (w *Workflows) ContinueAsNewWithVersionUpgradeV2(
ctx workflow.Context,
attempt int,
) (string, error) {
return "v2.0", nil
}
Upgrade on Continue-as-New is ideal for:
- Entity Workflows that represent long-lived business objects
- AI agents with long sleep intervals
- Batch processors that checkpoint progress
- Any Workflow that already uses Continue-as-New for history management
Choosing the right strategy#
The right Versioning Behavior depends on how long your Workflows run relative to how often you deploy. Here’s the decision framework:
| Workflow duration | Uses Continue-as-New? | Recommended behavior | Patching required? |
|---|---|---|---|
| Short (completes before next deploy) | N/A | PINNED |
Never |
| Medium (spans multiple deploys) | No | AUTO_UPGRADE |
Yes |
| Long (weeks to years) | Yes | PINNED + Upgrade on Continue-as-New |
Never |
| Long (weeks to years) | No | AUTO_UPGRADE + Patching |
Yes |
For most Workflows, the choice is straightforward. Order processing that completes in minutes: Pinned. Subscription billing that spans multiple deploys: Auto-Upgrade with patching. If you have long-running Workflows that already use Continue-as-New, the new Upgrade on Continue-as-New approach is the cleanest path to zero-patch deployments.
Getting started#
Worker Versioning is now Generally Available across all Temporal SDKs. To get started:
- Choose your Versioning Behavior for each Workflow type based on duration and deployment frequency
- Update your Workers to register with a deployment version
- Configure your deployment pipeline to create new versions on each deploy
Upgrade on Continue-as-New is available now in Public Preview. If you have long-running Workflows that already use Continue-as-New, this is a great time to try it.
Try both out and let us know what you think in the #safe-deploys channel on the Temporal Community Slack.