Migrations without downtime

Play this lesson

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:

Quick check

During the expand phase, what does the database have?

  1. Both seeds and seed_count, so old and new code both work
  2. Only seed_count
  3. 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

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.

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?

  1. Add the new column and write both, copy old data, switch reads, then drop the old column
  2. Drop the old column, then add the new one
  3. 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