Why Migrations Break Things — The Downtime Taxonomy

"Run the migration at 2 a.m." was a plan when users slept somewhere. For a system that's always on, every schema change, backfill, and datastore move must happen underneath live traffic — and the ways that goes wrong are surprisingly few and surprisingly repeatable: locks that queue the world, long transactions that starve it, mismatched assumptions between old code and new schema. This series is the discipline of changing data out from under a running system; this post is the map of how it breaks.

The Database Internals series explains how databases work; this series is about changing them while they work. The craft matters doubly now: migration windows shrank to zero at the same time as data volumes made every operation hours long — the squeeze that forced this discipline into existence.

The taxonomy of migration-induced downtime

Nearly every migration incident is one of five shapes:

The three vows

The discipline that answers this taxonomy rests on three commitments the whole series elaborates:

The series builds these into method: expand/contract for schema shape (post 2), batched throttled backfills (post 3), dual-write and shadow-read verification (post 4), cutover and rollback mechanics (post 5), cross-store moves via CDC (post 6), and the fleet view — migrations as a repeatable, increasingly automated capability rather than annual heroics (post 7).

The takeaway: migration incidents come in five repeatable shapes — lock queueing (duration × what’s behind it), resource starvation, long-transaction side effects, code-schema mismatch across rolling deploys, and silent semantic drift. The discipline against them is three vows: no locks proportional to data size, reversibility until a deliberate and late point of no return, and continuous proof over belief — and the rest of the series is those vows turned into method.

Key takeaways

Further reading

Sources & References

the practice this series makes survivable
the thing being engineered to zero