Skip to content
State and Consistency

06.05 · Concept

Migrations Against Live Traffic

Run an expand-contract migration and name the exact window in which rollback stops being possible.

No video curated for this lesson yet

This lesson is written, ordered and part of the path - the video slot is the only thing still open. We are working through Deployment lesson by lesson; 29 of 56 have their video so far.

The written notes below cover this idea in full - you lose nothing by reading instead of watching.

Expand-contract migration keeps old and new application versions working while a schema or data shape changes under live traffic. The safe sequence is to add compatible storage, write both forms, backfill in bounded batches, switch reads, then remove the old path only after every old runtime has drained.

What this lesson answers

  • how to migrate database schema with live traffic
  • when does rollback stop being safe in migrations
  • expand contract migration steps for rolling deploys

Notes

Migrations Against Live Traffic — Migrations against live traffic exist to change schemas or data while old and new application versions are both serving requests; without an expand-contract sequence, deploys can break when code reads a column that does not exist, writes a format old code cannot parse, or drops data still used by in-flight requests.

Key Concepts: - Expand phase: make the database backward-compatible first, e.g. `ALTER TABLE users ADD COLUMN display_name text NULL;` so old code using `name` and new code using `display_name` can both run.

Common questions

What is an expand-contract migration?
It is a deployment pattern for changing storage while production traffic continues. First you expand the schema so both old and new code can run. Then you write and backfill both representations, move reads to the new one, and finally contract by removing the old representation after no live code depends on it.
When is rollback no longer a normal deploy rollback?
Rollback stops being fully safe once production has committed data that old code cannot read, or once the old storage path has been removed. At that point reverting the application binary is not enough. You need a forward repair, a data conversion, or a restore strategy.
Why not drop the old column right after deploying new code?
During rolling deploys, old processes can still serve requests from load balancers, workers, queues, or scheduled jobs. If the old column disappears while any of them still reads or writes it, they can fail in production. The contract step waits until those versions are gone.