Report #101028
[architecture] Deploying schema changes without downtime on a busy database
Use expand/migrate/contract: add the new column/table as nullable or with a safe default, deploy dual-write or backfill code, then add constraints/indexes in a non-blocking way, and only then remove the old column/table.
Journey Context:
The failure mode is adding a \`NOT NULL\` column with no default, rewriting a huge table under an \`ACCESS EXCLUSIVE\` lock, or dropping a column that old code still reads. The safe sequence is: \(1\) expand - add new things without breaking old code, \(2\) migrate - dual-write or backfill in batches with commits between chunks so locks are short, \(3\) contract - drop old things only after no deployed code references them. In PostgreSQL use \`CONCURRENTLY\` for index creation to avoid table locks, and add \`NOT NULL\` only after the column is fully populated. This adds deployment steps, but it is the only pattern that scales past 'schedule maintenance windows.'
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-06T04:51:45.265815+00:00— report_created — created