Application-level dual-write migration pattern
Parent: Migration and Cutover Cost (Live Migration, mongosync, Dual-Running, Egress) · Published reference · snapshot 2026-10-31
↓ Facts as markdownall context files
Source-anchored research for Application-level dual-write migration pattern. Run status: COMPLETED.
These notes link each claim to its source. Some citations identify archived research reports that are no longer hosted on this site. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
Definitions
- Application dual writing is not an atomic cross-database commit. Without a transaction spanning both stores, a crash or failed second write can leave only one store updated; the application must provide recovery or reconciliation. (high confidence) [source]
How it works
- Even when every individual write succeeds, concurrent clients can apply updates in different orders at the two stores and leave different final values. Waiting alone does not repair this divergence. (high confidence) [source]
- Backfill can overwrite a concurrent live update with an older value. Tim Rutte recommends accepting a backfill record only when the target version is older and reconciling afterward; a blind upsert alone does not establish ordering safety. (low confidence) [source]
Comparisons and alternatives
- The archived Timescale dual-write/backfill guide scopes its approach to predominantly append-only time-series data, with updates and deletes absent or controlled; it explicitly describes low downtime rather than a universal zero-downtime guarantee. (low confidence) [source]
Facts and statements
- Application-level dual writing sends new mutations to both old and new stores during migration; historical records require a separate backfill before the destination is complete. (high confidence) [source]
- A staged cutover can keep reads on the old store during backfill, compare reads across stores, switch reads after validation, and retire old writes and data later. (high confidence) [source]
- Migration effort includes extra production writes, backfill work, comparison reads and application refactoring; these are separate costs from steady-state destination operation. This cost classification is a synthesis, not a measured dollar estimate. (medium confidence) [source]
- Kleppmann proposes a durable ordered log with independently tracked consumer positions to preserve write order and replay after failures; consumers remain asynchronous, so read-your-writes is not automatic. (low confidence) [source]
- Stripe's example treats mutation-path refactoring across services as a major challenge and removes the old representation only after checking that code no longer depends on it. (low confidence) [source]
- HighLevel's May 4, 2026 engineering account describes writing ingested and updated chunks to MongoDB and OpenSearch, progressively moving reads, and comparing quality, latency and index health; it presents dual writing as preserving a rollback path. (low confidence) [source]
- MongoDB's mongosync 1.11 release notes use 'dual write-blocking' to mean blocking destination writes during migration and source writes after commit. That term does not describe an application writing concurrently to both clusters. (low confidence) [source]
- A common application-level migration sequence duplicates new writes, backfills existing data, verifies and switches reads, then stops old writes and removes the old representation. Keeping these phases separate permits incremental rollout. (high confidence) [source]
- Cutover needs evidence of data equivalence beyond completion of the copy job. Stripe compared production read results and rechecked for missing objects; Rutte recommends counts, range checksums and focused field comparisons. (high confidence) [source]
- Migration effort includes changing and testing application access paths and transformations. Stripe identified write-path refactoring across services as especially challenging; Bussler separately identifies client-code modification and regression testing as dual-write responsibilities. (high confidence) [source]
- Budget for extra write and backfill load and for temporary maintenance of both representations. Stripe ramped duplicate writes while watching operational metrics; Rutte recommends throttled backfill and explicitly retiring the old write path. (high confidence) [source]
- A rollback window requires the old representation to remain current and capable of representing new data. Continuing duplicate writes after the read switch supports reversal, but incompatible new data can close that option before old writes stop. (low confidence) [source]
- Deletes and less-visible writers such as imports and maintenance scripts must participate in synchronization. Otherwise the target can retain deleted records or miss changes despite correct dual writes in the main request path. (low confidence) [source]
Children
- Dual-write partial-failure recovery (frontier)
- Backfill concurrency and delete handling (frontier)
- Shadow-read comparison and reconciliation (frontier)
- Read cutover and rollback window (frontier)
- Retiring temporary migration code (frontier)
Frontier under this node: Backfill concurrency and delete handling, Dual-write partial-failure recovery, Read cutover and rollback window, Retiring temporary migration code, Shadow-read comparison and reconciliation