Migrating a Cluster
ClusterMode.Migrating lets you retire a cluster without downtime or losing in-flight work — useful when moving to new infrastructure, changing a database provider, or consolidating clusters. A migrating cluster never locally dispatches or executes new work: held jobs and recurring schedules are continuously moved (not just referenced or proxied — physically relocated, then deleted from here) to another, healthy cluster, which does the actual dispatch/execution instead, while whatever is already in flight on this cluster drains out naturally.
Enabling it
Use MigrateTo(targetActiveClusterId) rather than Mode(ClusterMode.Migrating) directly — it sets the mode and the mandatory target together, so there's no way to end up in Migrating mode without a target:
config.MigrateTo("payroll-cluster-v2");
What happens
- No new buckets are created on the migrating cluster — it never onboards new work locally again.
- Jobs and recurring schedules held on the Master DB (
OnMaster) are continuously moved to the target cluster's own Master DB instead — inserted there, then deleted here. A job's full execution history (everyJobExecutionattempt) and itsJobExecution-category logs move with it, the same way they do when archiving a job — nothing about a held job's retry history is lost by migrating it. - Jobs already assigned to a bucket at the moment of the switch finish via the normal Drain path — nothing in flight is abandoned.
Execution-mode workers are not allowed on a migrating cluster (there's nothing left for them to execute, since no new buckets are ever created);Coordinator,Drain, andFullare all fine —Fullskips its execution runners and acts asCoordinator+Drain.
Typical migration workflow
- Stand up the new cluster (
"payroll-cluster-v2") asActive, alongside the existing one. - Point your producers/API traffic at the new cluster ID.
- Flip the old cluster into
Migratingmode viaMigrateTo("payroll-cluster-v2"). - Let it drain out naturally — the old cluster keeps running (so its Drain workers can finish existing buckets and forward anything held on master) until it's empty.
- Decommission the old cluster once it has no more buckets or held work.
Validation
Enforced at startup:
- A migrating cluster must have a target configured (
MigrateTo(...)) — an empty target throws. - The target can't be the cluster itself.
- The target must resolve to another configured cluster. That cluster must be
Active— either explicitly viaMode(ClusterMode.Active), or simply never configured with aModeat all, sinceActiveis the framework default. - Like
Archived, aMigratingcluster can't have any buckets explicitly configured on its workers.
See: Cluster Configuration · Archiving