You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Finalize draft for 0009-versioned-continue-as-new
* Fix non-Go languages
* Simplify examples, don't give an antipattern!
---------
Co-authored-by: skill-sync[bot] <skill-sync[bot]@users.noreply.github.com>
Co-authored-by: Donald Pinckney <donald.pinckney@temporal.io>
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
143
+
144
+
Long-running Pinned Workflows that use Continue-as-New can upgrade to newer Worker Deployment Versions at the Continue-as-New boundary without patching.
145
+
146
+
This pattern is for:
147
+
148
+
- Entity Workflows that run for months or years
149
+
- Batch processing Workflows that checkpoint with Continue-as-New
150
+
- AI agent Workflows with long sleeps waiting for user input
151
+
152
+
### How it works
153
+
154
+
By default, Pinned Workflows stay on their original Worker Deployment Version even when they Continue-as-New. With the upgrade option enabled:
155
+
156
+
1. Each Workflow run remains pinned to its version (no patching needed during a run).
157
+
2. The Temporal Server tells the Workflow when a new **Target Version** becomes available — that is, when the Workflow's Worker Deployment gets a new Current or Ramping Version that the Workflow would move to next.
158
+
3. When the Workflow performs Continue-as-New with the upgrade option, the new run starts on the Target Version.
159
+
160
+
### Detection flag
161
+
162
+
Active Workflows detect a Target Version change by checking a per-Workflow flag exposed on `WorkflowInfo` (called `target_worker_deployment_version_changed` in the docs). The flag is refreshed after each Workflow Task completes; check it from code that runs as part of a Workflow Task (for example, before accepting an Update, starting an Activity, or starting a child Workflow). See the per-language `references/{your_language}/versioning.md` for the SDK-specific call.
163
+
164
+
### Triggering the new run
165
+
166
+
When the flag is set, return a Continue-as-New error with the new run's initial Versioning Behavior set to `AutoUpgrade`. This makes the new run start on the Target Version of its Worker Deployment. The Workflow Type itself retains its Pinned annotation; only the *initial* behavior of the *new* run is overridden so it picks up the Target Version. Once the new run is on the new version, the per-Workflow-type annotation continues to apply on subsequent CaN.
167
+
168
+
### Limitations
169
+
170
+
-**Lazy moving only — sleeping Workflows do not auto-upgrade.** Send a Signal to wake an idle Workflow so it can check the flag.
171
+
-**Interface compatibility is your responsibility.** When continuing as new to a different version, the previous version's Workflow input must be compatible with the new version's Workflow definition. If incompatible, the new run may fail on its first Workflow Task.
172
+
-**Pinned Workflows only.** Auto-Upgrade Workflows already move to the Target Version at Workflow Task boundaries; this pattern adds nothing for them.
173
+
174
+
### When to use this pattern
175
+
176
+
- Workflow Type is Pinned **and**
177
+
- Workflow runs longer than your Worker Deployment Version lifetime **and**
178
+
- Workflow already uses Continue-as-New to bound Event History size.
179
+
180
+
For long-running Workflows that cannot use Continue-as-New (e.g., compliance audits that need full history), use `AUTO_UPGRADE` with patching instead.
181
+
139
182
## Choosing an Approach
140
183
141
184
| Scenario | Recommended Approach |
142
185
|----------|---------------------|
143
186
| Small change, few running workflows | Patching API |
144
187
| Major rewrite | Workflow Type Versioning |
145
188
| Many short workflows, frequent deploys | Worker Versioning (PINNED) |
Copy file name to clipboardExpand all lines: references/dotnet/versioning.md
+43Lines changed: 43 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -296,6 +296,49 @@ temporal workflow list --query \
296
296
'TemporalWorkerDeploymentVersion = "my-service:v1.0.0" AND ExecutionStatus = "Running"'
297
297
```
298
298
299
+
## Upgrading on Continue-as-New
300
+
301
+
> [!NOTE]
302
+
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
303
+
304
+
For long-running Pinned Workflows that use Continue-as-New, detect a new Target Worker Deployment Version on `Workflow.TargetWorkerDeploymentVersionChanged` and continue-as-new with `InitialVersioningBehavior.AutoUpgrade` so the new run starts on the Target Version. See `references/core/versioning.md` for the conceptual model.
305
+
306
+
### Detecting the Target Version change
307
+
308
+
`Workflow.TargetWorkerDeploymentVersionChanged` is `true` when a new Current or Ramping Version is available for this Workflow's Worker Deployment. The flag is refreshed after each Workflow Task completes.
309
+
310
+
Check the flag from code that runs as part of a Workflow Task — for example, before accepting an Update, starting an Activity, or starting a child Workflow.
311
+
312
+
### Continue-as-new with upgrade
313
+
314
+
When the flag is set, throw the exception from `Workflow.CreateContinueAsNewException`, passing a `ContinueAsNewOptions` whose `InitialVersioningBehavior` is `AutoUpgrade`, so the new run starts on the Target Version of its Worker Deployment.
315
+
316
+
```csharp
317
+
usingTemporalio.Common;
318
+
usingTemporalio.Workflows;
319
+
320
+
// At a natural Workflow Task boundary, e.g. before accepting Updates,
> Don't busy-poll the flag on a timer. Check it at a natural Workflow Task boundary — before accepting Updates, starting Activities, starting child Workflows, etc. For idle Workflows, send a Signal to wake them so they can check it (see Limitations).
335
+
336
+
### Limitations
337
+
338
+
-**Lazy moving only — idle Workflows do not upgrade.** Send a Signal to wake an idle Workflow so it can check `TargetWorkerDeploymentVersionChanged`.
339
+
-**Workflow input must remain compatible across versions.** The new version's Workflow definition must accept the previous version's input; otherwise the new run may fail on its first Workflow Task.
340
+
-**Pinned Workflow Types only.** Auto-Upgrade Workflows move at Workflow Task boundaries already; the upgrade-on-CaN pattern adds nothing for them.
341
+
299
342
## Best Practices
300
343
301
344
1.**Check for open executions** before removing old code paths
Copy file name to clipboardExpand all lines: references/go/versioning.md
+41Lines changed: 41 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -226,6 +226,47 @@ temporal workflow list --query \
226
226
'TemporalWorkerDeploymentVersion = "my-service:v1.0.0" AND ExecutionStatus = "Running"'
227
227
```
228
228
229
+
## Upgrading on Continue-as-New
230
+
231
+
> [!NOTE]
232
+
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
233
+
234
+
For long-running Pinned Workflows that use Continue-as-New, detect a new Target Worker Deployment Version on `WorkflowInfo` and continue-as-new with `ContinueAsNewVersioningBehaviorAutoUpgrade` so the new run starts on the Target Version. See `references/core/versioning.md` for the conceptual model.
235
+
236
+
### Detecting the Target Version change
237
+
238
+
`workflow.GetInfo(ctx).GetTargetWorkerDeploymentVersionChanged()` returns `true` when a new Current or Ramping Version is available for this Workflow's Worker Deployment. The flag is refreshed after each Workflow Task completes.
239
+
240
+
Check the flag from code that runs as part of a Workflow Task — for example, before accepting an Update, starting an Activity, or starting a child Workflow.
241
+
242
+
### Continue-as-new with upgrade
243
+
244
+
When the flag is set, return `workflow.NewContinueAsNewErrorWithOptions` with `InitialVersioningBehavior: workflow.ContinueAsNewVersioningBehaviorAutoUpgrade` so the new run starts on the Target Version of its Worker Deployment.
245
+
246
+
```go
247
+
// At a natural Workflow Task boundary, e.g. before accepting Updates,
> Don't busy-poll the flag on a timer. Check it at a natural Workflow Task boundary — before accepting Updates, starting Activities, starting child Workflows, etc. For idle Workflows, send a Signal to wake them so they can check it (see Limitations).
263
+
264
+
### Limitations
265
+
266
+
-**Lazy moving only — idle Workflows do not upgrade.** Send a Signal to wake an idle Workflow so it can check `GetTargetWorkerDeploymentVersionChanged`.
267
+
-**Workflow input must remain compatible across versions.** The new version's Workflow definition must accept the previous version's input; otherwise the new run may fail on its first Workflow Task.
268
+
-**Pinned Workflow Types only.** Auto-Upgrade Workflows move at Workflow Task boundaries already; the upgrade-on-CaN pattern adds nothing for them.
269
+
229
270
## Best Practices
230
271
231
272
1.**Keep GetVersion calls** even when only a single branch remains -- it guards against stale replays and simplifies future changes
'TemporalWorkerDeploymentVersion = "order-service:v1.0.0" AND ExecutionStatus = "Running"'
272
272
```
273
273
274
+
## Upgrading on Continue-as-New
275
+
276
+
> [!NOTE]
277
+
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
278
+
279
+
For long-running Pinned Workflows that use Continue-as-New, detect a new Target Worker Deployment Version on `Workflow.getInfo()` and continue-as-new with `InitialVersioningBehavior.AUTO_UPGRADE` so the new run starts on the Target Version. See `references/core/versioning.md` for the conceptual model.
280
+
281
+
### Detecting the Target Version change
282
+
283
+
`Workflow.getInfo().isTargetWorkerDeploymentVersionChanged()` returns `true` when a new Current or Ramping Version is available for this Workflow's Worker Deployment. The flag is refreshed after each Workflow Task completes.
284
+
285
+
Check the flag from code that runs as part of a Workflow Task — for example, before accepting an Update, starting an Activity, or starting a child Workflow.
286
+
287
+
### Continue-as-new with upgrade
288
+
289
+
When the flag is set, call `Workflow.continueAsNew` with a `ContinueAsNewOptions` whose `InitialVersioningBehavior` is `AUTO_UPGRADE` so the new run starts on the Target Version of its Worker Deployment.
> Don't busy-poll the flag on a timer. Check it at a natural Workflow Task boundary — before accepting Updates, starting Activities, starting child Workflows, etc. For idle Workflows, send a Signal to wake them so they can check it (see Limitations).
309
+
310
+
### Limitations
311
+
312
+
-**Lazy moving only — idle Workflows do not upgrade.** Send a Signal to wake an idle Workflow so it can check `isTargetWorkerDeploymentVersionChanged`.
313
+
-**Workflow input must remain compatible across versions.** The new version's Workflow definition must accept the previous version's input; otherwise the new run may fail on its first Workflow Task.
314
+
-**Pinned Workflow Types only.** Auto-Upgrade Workflows move at Workflow Task boundaries already; the upgrade-on-CaN pattern adds nothing for them.
315
+
274
316
## Best Practices
275
317
276
318
1.**Check for open executions** before removing old code paths
Copy file name to clipboardExpand all lines: references/python/versioning.md
+39Lines changed: 39 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -322,6 +322,45 @@ temporal workflow list --query \
322
322
'TemporalWorkerDeploymentVersion = "my-service:v1.0.0" AND ExecutionStatus = "Running"'
323
323
```
324
324
325
+
## Upgrading on Continue-as-New
326
+
327
+
> [!NOTE]
328
+
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
329
+
330
+
For long-running Pinned Workflows that use Continue-as-New, detect a new Target Worker Deployment Version on `workflow.info()` and continue-as-new with `ContinueAsNewVersioningBehavior.AUTO_UPGRADE` so the new run starts on the Target Version. See `references/core/versioning.md` for the conceptual model.
331
+
332
+
### Detecting the Target Version change
333
+
334
+
`workflow.info().is_target_worker_deployment_version_changed()` returns `True` when a new Current or Ramping Version is available for this Workflow's Worker Deployment. The flag is refreshed after each Workflow Task completes.
335
+
336
+
Check the flag from code that runs as part of a Workflow Task — for example, before accepting an Update, starting an Activity, or starting a child Workflow.
337
+
338
+
### Continue-as-new with upgrade
339
+
340
+
When the flag is set, call `workflow.continue_as_new` with `initial_versioning_behavior=ContinueAsNewVersioningBehavior.AUTO_UPGRADE` so the new run starts on the Target Version of its Worker Deployment.
341
+
342
+
```python
343
+
from temporalio import workflow
344
+
from temporalio.workflow import ContinueAsNewVersioningBehavior
345
+
346
+
# At a natural Workflow Task boundary, e.g. before accepting Updates,
> Don't busy-poll the flag on a timer. Check it at a natural Workflow Task boundary — before accepting Updates, starting Activities, starting child Workflows, etc. For idle Workflows, send a Signal to wake them so they can check it (see Limitations).
357
+
358
+
### Limitations
359
+
360
+
-**Lazy moving only — idle Workflows do not upgrade.** Send a Signal to wake an idle Workflow so it can check `is_target_worker_deployment_version_changed`.
361
+
-**Workflow input must remain compatible across versions.** The new version's Workflow definition must accept the previous version's input; otherwise the new run may fail on its first Workflow Task.
362
+
-**Pinned Workflow Types only.** Auto-Upgrade Workflows move at Workflow Task boundaries already; the upgrade-on-CaN pattern adds nothing for them.
363
+
325
364
## Best Practices
326
365
327
366
1.**Check for open executions** before removing old code paths
Copy file name to clipboardExpand all lines: references/typescript/versioning.md
+40Lines changed: 40 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -204,6 +204,46 @@ Worker Versioning is best suited for:
204
204
205
205
For long-running Workflows, consider combining Worker Versioning with the Patching API, or use Continue-as-New to move Workflows to newer versions.
206
206
207
+
## Upgrading on Continue-as-New
208
+
209
+
> [!NOTE]
210
+
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
211
+
212
+
For long-running Pinned Workflows that use Continue-as-New, detect a new Target Worker Deployment Version on `workflowInfo()` and continue-as-new with `InitialVersioningBehavior.AUTO_UPGRADE` so the new run starts on the Target Version. See `references/core/versioning.md` for the conceptual model.
213
+
214
+
### Detecting the Target Version change
215
+
216
+
`workflowInfo().targetWorkerDeploymentVersionChanged` is `true` when a new Current or Ramping Version is available for this Workflow's Worker Deployment. The flag is refreshed after each Workflow Task completes.
217
+
218
+
Check the flag from code that runs as part of a Workflow Task — for example, before accepting an Update, starting an Activity, or starting a child Workflow.
219
+
220
+
### Continue-as-new with upgrade
221
+
222
+
When the flag is set, build the Continue-as-New function with `makeContinueAsNewFunc`, passing `initialVersioningBehavior: InitialVersioningBehavior.AUTO_UPGRADE`, so the new run starts on the Target Version of its Worker Deployment.
> Don't busy-poll the flag on a timer. Check it at a natural Workflow Task boundary — before accepting Updates, starting Activities, starting child Workflows, etc. For idle Workflows, send a Signal to wake them so they can check it (see Limitations).
240
+
241
+
### Limitations
242
+
243
+
-**Lazy moving only — idle Workflows do not upgrade.** Send a Signal to wake an idle Workflow so it can check `targetWorkerDeploymentVersionChanged`.
244
+
-**Workflow input must remain compatible across versions.** The new version's Workflow definition must accept the previous version's input; otherwise the new run may fail on its first Workflow Task.
245
+
-**Pinned Workflow Types only.** Auto-Upgrade Workflows move at Workflow Task boundaries already; the upgrade-on-CaN pattern adds nothing for them.
246
+
207
247
## Best Practices
208
248
209
249
1. Use descriptive `patchId` names that explain the change
0 commit comments