Temporal Affiliation
Content Suggestion
I could not find clear migration steps on moving from Unversioned to Versioned Worker Versioning so I compiled one.
Migrating from Unversioned to Versioned Temporal Workers (No Worker Controller)
This guide aims to aid adoption of Worker Versioning when the Temporal Worker Controller is not being used.
If you are using the Temporal Worker Controller, follow this guide.
Prerequisites
- Unversioned Temporal workers currently running in production
- Temporal CLI >= 1.5.0
- Workers connect to Temporal with namespace and task queue configuration
Step 1: Update Your Worker Code
Update your worker initialization to include versioning configuration.
Before (Unversioned):
// Worker connects without versioning
worker := worker.New(client, "my-task-queue", worker.Options{})
After (Versioned):
buildID := os.Getenv("TEMPORAL_WORKER_BUILD_ID")
deploymentName := os.Getenv("TEMPORAL_DEPLOYMENT_NAME")
if buildID == "" || deploymentName == "" {
// exit with an error
}
workerOptions := worker.Options{
DeploymentOptions: worker.DeploymentOptions{
UseVersioning: true,
Version: worker.WorkerDeploymentVersion{
DeploymentName: deploymentName,
BuildID: buildID,
},
},
}
worker := worker.New(client, "my-task-queue", workerOptions)
⚠️ Important: Your versioned worker code must be fully backward-compatible
with existing unversioned workflow histories to avoid non-determinism errors.
Do not make breaking workflow code changes at this stage.
Step 2: Deploy Your Versioned Worker
Deploy your versioned worker alongside your existing unversioned workers.
The versioned worker will begin polling but will not receive any tasks until
you explicitly activate it via the CLI.
You can verify it is polling by inspecting the Worker Deployment:
temporal worker deployment describe --name "YourDeploymentName"
Step 3: Gradually Ramp Traffic (Optional but Recommended)
Rather than cutting over all at once, ramp a small percentage of new workflow
executions to the versioned worker first:
temporal worker deployment set-ramping-version \
--deployment-name "YourDeploymentName" \
--build-id "YourBuildID" \
--percentage=5
Monitor workflows on the new version:
temporal workflow describe -w YourWorkflowID
This returns versioning info such as:
Versioning Info:
Behavior AutoUpgrade
Version YourDeploymentName.YourBuildID
OverrideBehavior Unspecified
Increase the ramp percentage incrementally as you gain confidence.
Step 4: Set the Versioned Worker as Current
Once validated, promote the versioned worker to receive 100% of new workflow executions:
temporal worker deployment set-current-version \
--deployment-name "YourDeploymentName" \
--build-id "YourBuildID"
⚠️ Once a Current version is set, unversioned workers will no longer receive
any tasks. Ensure your versioned workers are healthy before this step.
Step 5: Migrate Unversioned In-Flight Workflows
After setting the Current version, unversioned in-flight workflows are not dropped.
On their next task execution, they will automatically be routed to the versioned worker.
Once they land on a versioned worker, they will become either Pinned or AutoUpgrade
depending on the workflow's versioning behavior annotation.
⚠️ Sleeping or idle workflows will not automatically wake up to receive the
new version information. If you have workflows that are sleeping or waiting for an
event, you must send them a Signal to wake them up so they can be dispatched to
the versioned worker on their next task execution.
To signal all running workflows at once:
temporal workflow signal \
--query "ExecutionStatus='Running'" \
--name "wake-up" \
--namespace production \
--rps 100
Once signaled, those workflows will execute a Workflow Task and be routed to the
Current versioned worker.
Keep your unversioned workers running until all in-flight workflows have migrated over.
Step 6: Scale Down and Clean Up Unversioned Workers
Only after confirming all workflows are handled by versioned workers, shut down
your old unversioned worker deployments.
Key Principles
- ✅ Deploy the versioned worker first — it won't receive tasks until activated
- ✅ Ensure versioned code is backward-compatible with existing workflow histories
- ✅ Use ramping to gradually shift traffic before full cutover
- ✅ Signal sleeping/idle workflows to wake them up and migrate them to the versioned worker
- ✅ Keep unversioned workers running during the transition period
- ✅ Test thoroughly in non-production before migrating production workers
Temporal Affiliation
Content Suggestion
I could not find clear migration steps on moving from Unversioned to Versioned Worker Versioning so I compiled one.
Migrating from Unversioned to Versioned Temporal Workers (No Worker Controller)
This guide aims to aid adoption of Worker Versioning when the Temporal Worker Controller is not being used.
If you are using the Temporal Worker Controller, follow this guide.
Prerequisites
Step 1: Update Your Worker Code
Update your worker initialization to include versioning configuration.
Before (Unversioned):
After (Versioned):
Step 2: Deploy Your Versioned Worker
Deploy your versioned worker alongside your existing unversioned workers.
The versioned worker will begin polling but will not receive any tasks until
you explicitly activate it via the CLI.
You can verify it is polling by inspecting the Worker Deployment:
temporal worker deployment describe --name "YourDeploymentName"Step 3: Gradually Ramp Traffic (Optional but Recommended)
Rather than cutting over all at once, ramp a small percentage of new workflow
executions to the versioned worker first:
temporal worker deployment set-ramping-version \ --deployment-name "YourDeploymentName" \ --build-id "YourBuildID" \ --percentage=5Monitor workflows on the new version:
This returns versioning info such as:
Increase the ramp percentage incrementally as you gain confidence.
Step 4: Set the Versioned Worker as Current
Once validated, promote the versioned worker to receive 100% of new workflow executions:
temporal worker deployment set-current-version \ --deployment-name "YourDeploymentName" \ --build-id "YourBuildID"Step 5: Migrate Unversioned In-Flight Workflows
After setting the Current version, unversioned in-flight workflows are not dropped.
On their next task execution, they will automatically be routed to the versioned worker.
Once they land on a versioned worker, they will become either Pinned or AutoUpgrade
depending on the workflow's versioning behavior annotation.
To signal all running workflows at once:
temporal workflow signal \ --query "ExecutionStatus='Running'" \ --name "wake-up" \ --namespace production \ --rps 100Once signaled, those workflows will execute a Workflow Task and be routed to the
Current versioned worker.
Keep your unversioned workers running until all in-flight workflows have migrated over.
Step 6: Scale Down and Clean Up Unversioned Workers
Only after confirming all workflows are handled by versioned workers, shut down
your old unversioned worker deployments.
Key Principles