Database migrations fail without downtime when application and schema changes assume they become active simultaneously. In a rolling deployment, old and new instances coexist, replicas lag, and background jobs may continue using yesterday's contract.
Zero-downtime migration is a compatibility discipline rather than a deployment flag. This guide explains expand-and-contract changes, backfills, verification, and rollback planning for systems that must remain available.
Expand before switching
Add nullable columns, new tables, indexes, or APIs in backward-compatible form. Deploy application code that can operate with both old and new structures. Avoid renames and destructive constraints in the same release that introduces their replacements.
Move data safely
Backfill in bounded batches with checkpoints, throttling, and observable progress. Design the operation to resume after interruption. For large datasets, account for locking, transaction logs, replica lag, and index creation behavior under production load.
Shift reads and writes deliberately
Use dual writes only with clear consistency and repair strategies; they are not automatically safe. Compare old and new results, then switch reads behind a controlled flag. Keep rollback possible until the new path has survived realistic traffic and reconciliation.
Contract after evidence
Remove old fields, code, and compatibility paths in a later release after confirming no consumers remain. Record migration ownership and cleanup dates. Rehearse on production-like data, measure lock behavior, and test rollback before scheduling the live sequence.
