Safe Consistency Migration Workflow¶
Migration workflow — instantiates Shared-State Consistency Contract Design
Changes a live system's consistency semantics in reversible, observable stages — dual paths, shadow comparison, staged cutover — instead of flipping the guarantee as a silent config change.
Safe Consistency Migration Workflow is the procedure for changing what a running system promises about shared state — eventual to causal, last-write-wins to a merge type, single-region to multi-region — without breaking clients who depend on the old promise. Its defining stance is that a semantics change is a migration, not a toggle: it must be staged, reversible at each step, observed while both behaviors run in parallel, and recorded so that "what did a successful operation mean on this date" is always answerable. This directly counters the archetype's named failure — deploying a semantic change as an ordinary configuration flip, where clients silently start relying on a guarantee that quietly changed underneath them.
Example¶
A store keeps shopping carts in a last-write-wins register, which silently drops an item when a customer adds from two devices at once. The team wants to move to an add-wins CRDT set that keeps both. Rather than flip the storage type, they run the migration in stages: (1) dual-write — every cart mutation writes both the old register and the new CRDT; (2) shadow-read and compare — reads still serve the old value, but an oracle compares what the CRDT would have returned and logs divergences; (3) staged cutover — reads move to the CRDT one customer cohort at a time behind a flag, each cohort independently rollback-able; (4) backfill historical carts; (5) retire the old path. The audit trail records the exact moment each cohort's semantics changed, so a later dispute ("the cart lost an item on the 3rd") can be answered against the semantics actually in force then. When a cohort's divergence spikes, the flag rolls back with no customer impact.
How it works¶
The distinguishing structure is expand/contract applied to semantics: add the new behavior alongside the old, migrate consumers gradually, then remove the old — so no single step is a breaking flip.[1] A comparison oracle runs during the shadow stage to catch client-visible behavior changes before any cutover, and every stage transition is reversible and recorded. The workflow does not decide which new guarantee to adopt (that is a design decision made elsewhere); it is the machinery for getting there safely on live state.
Tuning parameters¶
- Stage granularity / cohort size — small cohorts shrink blast radius but lengthen the migration.
- Shadow duration & compare threshold — longer shadowing and tighter thresholds raise confidence at the cost of time.
- Rollback trigger — how aggressively a divergence or SLO breach auto-reverts a cohort: safety vs. churn.
- Path strategy — dual-write, dual-read, or both, chosen to match the kind of change (write-semantics vs. read-semantics).
- Backfill strategy — whether and how historical data is converted, trading completeness against load.
When it helps, and when it misleads¶
Its strength is turning a scary, seemingly-irreversible semantics flip into an evidence-gated, reversible rollout that is auditable after the fact and catches surprises in shadow before customers feel them.
It misleads when the dual-run stages are themselves mishandled. Dual-writes that are not idempotent or correctly ordered can introduce the very inconsistency the migration is meant to fix; long parallel-run windows are costly and tempt teams to skip the comparison. The backwards version is flipping the flag first and writing the migration story afterward — precisely the silent-config-change anti-pattern in disguise. The discipline is to never change semantics as a bare config value: keep the old path live until the shadow comparison is clean, and record every cutover.
How it implements the components¶
consistency_migration_plan— the staged, reversible plan (dual-path, shadow, cohorted cutover, backfill, retire) that carries a live system from one guarantee to another.audit_trail— the durable record of which semantics was in effect for whom and when, so a change is never silent and past behavior stays explainable.
It does not choose the target guarantee (consistency_guarantee_profile, client_facing_semantics_contract) — that is Consistency Contract Decision Record — nor supply the shadow-stage comparison oracle (Sequential-Consistency Trace Protocol / Consistency History Checker) or the rollout dashboards (Replica-Lag and Freshness Dashboard).
Related¶
- Instantiates: Shared-State Consistency Contract Design — governs how the contract itself is allowed to change over time.
- Consumes: a comparison oracle for the shadow stage and Replica-Lag and Freshness Dashboard to watch each cohort.
- Sibling mechanisms: Consistency Contract Decision Record · Sequential-Consistency Trace Protocol · Replica-Lag and Freshness Dashboard · Consistency History Checker
Notes¶
The migration's own machinery can be a source of inconsistency: a dual-write is a two-target write, so unless each side is idempotent and ordered, a partial failure leaves the two representations disagreeing. Treat the dual-write path as its own small consistency problem — reconcilable on retry — rather than assuming it is safe because it is temporary.
References¶
[1] Expand/contract (a.k.a. parallel change, Fowler) — evolve an interface by first adding the new form, migrating consumers, then removing the old, so no step is a breaking change. Here it is applied to consistency semantics rather than to a schema or API. ↩