Migrations without downtime
A rename during a deploy
Remy wants to rename the seeds column to seed_count. A change to a database's shape is called a migration.
During a deploy, old and new servers run side by side for a few minutes. If the column is renamed in one step, the old servers break at once, mid-match.
Expand, migrate, contract
Danilo Sato's "parallel change", on Martin Fowler's site, makes a breaking change in three phases:
- Expand"augment the interface to support both the old and the new versions."
- Migrate"update all clients using the old version to the new version."
- Contract"remove the old version" once nothing uses it.
Quick check
During the expand phase, what does the database have?
- Both seeds and seed_count, so old and new code both work
- Only seed_count
- Neither column
Show the answer
Both seeds and seed_count, so old and new code both work
Expanding adds the new shape without removing the old, so every server, old or new, finds what it expects.
seed_count, step by step
- Add
seed_count, and write every change to both columns. - Copy the old values across, a backfill.
- Switch reads to
seed_count. - When no code reads
seeds, drop it.
Each step is its own deploy and can be undone on its own.
Quick check
Renaming a column in one step is safe while old and new servers run side by side.
- True
- False
Show the answer
False
Old servers still use the old name. For those minutes, every request they handle fails.
The long middle
Sato notes that the migrate phase can take the longest, especially when clients outside the team's control use the old version. For a game, that means app versions on players' phones, which update in their own time.
Pick the order
Which order lets Remy rename the column safely?
- Add the new column and write both, copy old data, switch reads, then drop the old column
- Drop the old column, then add the new one
- Switch reads first, then add the new column
Show the answer
Add the new column and write both, copy old data, switch reads, then drop the old column
At every step, both old and new code find what they need. The old column goes only when nothing reads it.
Changes that must happen once
Deploys and migrations get retried when something hiccups. Some actions, like charging a player, must never happen twice.
Bolt says: Next: idempotency and retries.
Fact-checked 12 October 2026
- Danilo Sato: ParallelChange martinfowler.com