Skip to content
Knowledge Hub

Ordering: rename a column with zero downtime Intermediate

Estimated reading time: 1 min read

Renaming a column sounds simple: one ALTER TABLE ... RENAME COLUMN statement. But during a rolling deploy, the old and new app versions run at the same time. One of them will read a column that does not exist.

Put the steps below in order. Press Check to see which steps are out of place and what breaks when they are.

Ordering

Rename column status → payment_status with zero downtime

The orders table has 50 million rows, the app runs 6 pods and deploys with rolling updates: during a rollout, the old and new versions run side by side.

Put the steps in order so that no request fails and you can always roll back.

Use ▲▼ to move each step, or tap a step’s ⠿ and then tap its new position. On a computer you can drag and drop.

  1. Backfill old rows in batches, then reconcile until mismatches = 0UPDATE ... WHERE id BETWEEN $1 AND $2
  2. Deploy an app that writes both columns and still reads status
  3. DROP COLUMN status in a separate migration
  4. Add the payment_status column (nullable) under a lock_timeout
  5. Deploy an app that reads payment_status and still writes both
  6. Rollback window over: deploy an app that stops writing status and removes the column from the ORM

A full explanation of each phase, including NOT NULL and indexes that do not lock the table: Expand–contract migration.