World map

 

BM: Baca dalam Bahasa Melayu

World C3: Release & Deploy

Database changes without downtime

You will learn: how to change a database in safe steps while old and new code both run.

Checked with GitHub Actions 2026-10 on 31 Oct 2026

The problem

psql
psql -c "SELECT phone FROM customers;"
ERROR: column "phone" does not exist
LINE 1: SELECT phone FROM customers;
^
The old code asks for the phone column. PostgreSQL says the column does not exist.

You renamed the column phone to mobile. Version 2 is happy. But version 1 copies still run during the rollout. Plain words: old code asks for a column that is gone.

Watch

During a rolling or canary deploy, who reads and writes the database?

Pick one answer.

Watch

The fix is expand and contract: Change a database in safe steps: add the new shelf, move the stock, then remove the old shelf. Old and new code keep working.. Change the pantry in safe steps. Add the new shelf, move the stock, then remove the old one. Put the steps in order.

First step at the top. Put these in order. Use the arrows, or drag.

  • Contract: drop the old phone column
  • Expand: add the new column, mobile
  • Deploy code that writes to both columns
  • Migrate: copy old numbers into mobile
  • Deploy code that uses only mobile

Try it

Which changes are safe in one deploy? Sort them.

Drag a card into a box. Or tap the card, then tap the box.

      Predict

      You are at step 2: both columns exist. Version 2 has a bug. Can you roll back to version 1?

      Pick one answer.

      Check

      psql
      psql -c "ALTER TABLE customers ADD COLUMN mobile text;"
      ALTER TABLE
      psql -c "SELECT id, phone, mobile FROM customers;"
      id | phone | mobile
      ----+-------------+--------
      1 | 012-3456789 |
      (1 row)
      Add the mobile column. The table now has id, phone and an empty mobile.

      Step 1 for real, on PostgreSQL 18. ADD COLUMN adds an empty shelf. Old code still reads phone. New code can start writing mobile.

      You did it!

      You can now change a database without closing the shop.

      Go deeper (optional)

      Run each migration as its own step, before the code that needs it. Some changes lock a big table while they run. Read your database’s docs first. And remember: a rollback swaps code, not data. Cloudflare’s rollback leaves databases and other bindings as they are.

      Real rep (optional): try these steps on a throwaway database: docker run --rm -e POSTGRES_PASSWORD=test postgres:18-alpine.