Expand and contract changes

Cloud, deploys and infrastructure Mid-level Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Order the steps

Order renaming fullname to display_name with no downtime.

  • Drop fullname in a later release
  • Backfill display_name in batches
  • Deploy code that writes both and reads display_name with a fallback
  • Add display_name as a nullable column
  • Deploy code that uses only display_name

Choose an answer, then open Show answer below to check it.

Show answer

Answer: D C B E A

  1. Add display_name as a nullable column Old code ignores it.
  2. Deploy code that writes both and reads display_name with a fallback Old and new code both work.
  3. Backfill display_name in batches Every row now has it.
  4. Deploy code that uses only display_name Nothing reads fullname now.
  5. Drop fullname in a later release The contract step.

30-second answer

Split the change so every step works with both versions. Expand: add the new column (or field) alongside the old. Migrate: deploy code that writes both and reads the new with a fallback, then backfill old rows in batches. Switch: deploy code that reads and writes only the new. Contract: once no running code uses the old column, drop it. Each step is separately deployable and reversible, which is what rolling deploys need.

Practise saying it · 35 s. No recording, just a timer

Expand and contract.

Say your answer out loud, then check which of these points you covered:

  • Expand
  • Dual write, fallback read
  • Batched backfill
  • Switch
  • Contract later

Deep dive

The same pattern works for API fields, message schemas and cache formats.

Backfill in small batches to avoid long locks and replica lag.

Add constraints as NOT VALID, then VALIDATE separately in Postgres.

Leave a gap of at least one full release before the contract step.

Expand, backfill, then contract Ran on PostgreSQL 17.11
SQL · PostgreSQL 17
CREATE TEMP TABLE users (id int, fullname text);
INSERT INTO users VALUES (1, 'Ana Rao');
ALTER TABLE users ADD COLUMN display_name text;
UPDATE users SET display_name = fullname
WHERE display_name IS NULL;
ALTER TABLE users DROP COLUMN fullname;
SELECT display_name FROM users;

Common mistakes

  • Renaming a column in one migration while old code still runs.
  • Backfilling millions of rows in one transaction.
  • Dropping the old column in the same release that stops writing it.

Senior take & follow-ups

Name the four phases, why rolling deploys need them, and backfill safety.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why can't you rename in one step?

    Show hint

    During a rolling deploy, old instances still query the old name.

  2. How do you backfill safely?

    Show hint

    Batches by key range, with pauses, outside peak.

Suggest a fix if something here is wrong or out of date.