Worker versioning and workflow routing

Hello. I am trying to implement a blue green deployment strategy using worker versioning, but I am not sure if temporal supports this.

We 2 services running: REST server and workflow service. REST server receives a request and triggers the workflow which will run in workflow service. Temporal versioning allows ramping based on percentage, but we would like to control the routing based on an http header that is received in the REST server.

REST server is always receiving traffic which may or may not have the routing header. The routing behavior we want is the following:

  1. If header is present and green workflow version is running, REST server should start the workflow on green workflow version.
  2. If header is present and green workflow version is not running, we want to start that workflow on the current live version.
  3. If header is not present, start workflow on current live version.

We also don’t want the workflows to be pinned in case of rollback.

I know we can use setVersionOverride to pin a specific workflow to a specific version, but there are 2 issue I see:

  1. Workflows are pinned and would require manual intervention if we want to change the version.
  2. We would need the REST server to know which versions of the workflow service exist to do the routing based on deployment name and build id.

Is this possible? Or is there a different pattern that is advisable?

Hi Steve, I’m one of the engineers who worked on Worker Versioning. Thanks for the detailed question. Before we get into header-based routing, I want to focus on this comment, because it suggests there may be a subtle but important misunderstanding about how rollback behaves with Pinned vs AutoUpgrade workflows:

“We also don’t want the workflows to be pinned in case of rollback.”

If a workflow starts on v2 and is Pinned* there:

  • It continues running on v2.
  • If you roll Current back to v1, new workflows start on v1.
  • Existing workflows stay safely on v2.
  • No replay compatibility risk is introduced by the rollback.
    • When you’ve deployed a v2.1 that fixes the bug in v2, you can manually move workflows to that fixed build with temporal workflow update-options.

If a workflow starts on v2 and is AutoUpgrade*:

  • It always routes to whatever version is the Target Version*.
  • If you roll the Target Version (typically the Current Version) back to v1, the next Workflow Task goes to v1.
  • If v1 cannot replay history generated by v2, the workflow hits a non-determinism error and becomes stuck.

“Rollback” with AutoUpgrade is only safe if:

  • You roll forward to a compatible v2.1 instead of reverting to v1, or
  • You are able to manually reset the workflows that ran on buggy v2 so that they can run on v1.

So if your concern is “we don’t want rollback to break running workflows,” pinned workflows are safer in terms of avoiding stuck workflows.

*See Worker Versioning | Temporal Platform Documentation for definitions of these terms.


You called out two valid concerns about starting workflows with Versioning Override, based on the header value:

Workflows are pinned and would require manual intervention if we want to change the version.

Yes, when you start a workflow with an override, you’re making an explicit decision about what version you want your workflow to use. That workflow is isolated from deployment routing changes unless you change or remove the override. This prevents automatic upgrades, but also prevents replay failures after rollback.

You have to choose which properties matter most:

  • Header-controlled routing
  • Automatic migration between versions
  • Rollback safety from NDEs

We would need the REST server to know which versions of the workflow service exist to do the routing based on deployment name and build id.

Also yes, if the application is deciding which version to target, it must know Deployment Name and Build ID.

That coupling is unavoidable if routing decisions live in the application layer. Your application layer could get those values by listing the versions in your Worker Deployment and checking timestamps to find the most recently created one, but if you want to remove that coupling, you need to let Temporal do the routing via Current/Ramping.


Now I’ll write out two patterns I can think of that fit a blue-green system. Regardless of which one you go with, you’ll need to decide whether to use Pinned or AutoUpgrade base behavior for your workflows.


Gradual Ramp:

  1. Blue is Current.
  2. Deploy Green.
  3. Set Green as Ramping (start at 0%, increase gradually).
  4. When satisfied, promote Green to Current.
  5. Leave Blue running until pinned workflows drain.

This is what Worker Versioning is primarily designed around. It achieves a conservative gradual rollout, but does not let you explicitly decide whether a specific workflow uses the blue or green version. (Note: Whether a certain workflow uses the Ramping version or Current version is deterministically based on a hash of the Workflow ID, so you could purposely generate workflow IDs that fall into the blue or green bucket and kind of get header-based routing that way).


Header-based with Versioning Override:

  1. Blue is Current.
  2. Deploy Green.
  3. REST inspects the header.
  4. If header present → start workflow with VersioningOverride to Green.
  5. Otherwise → no override (defaults to Current).
  6. Once satisfied with the Green cohort, promote Green to Current.
  7. Optionally, run a batch job to search for workflows with the Green override and remove the override.

Note: Removing the override does not move those workflows. But from that point forward, their behavior is governed by the workflow’s own Pinned vs AutoUpgrade setting and the Worker Deployment’s Current/Ramping configuration, not by a forced override. This leaves you with no permanently “special” cohort of overridden workflows after the green rollout period, which is nice.


Hope this helps! Let me know if you have any follow up questions or want to dig in further on any of these concepts

Hi Carly,

Thank you so much for the in depth response. This really helps to clarify my understanding of how the versioning is working. The second suggestion you made is exactly what I implemented as a POC. I may have more questions in the future but this is extremely helpful for now. Thanks!!

1 Like

Hi @carlydf

I’m continuing to experiment with your suggestions and ran across this post regarding activity versioning: https://community.temporal.io/t/activity-versioning/17896/4

We have the exact same requirement as the poster. We would like to be able to route a workflow to a specific version of an activity. I believe the feature in question is here: https://github.com/temporalio/temporal/issues/8113 I just wanted to check if there was any work around while this feature is in progress.

Thank you!