PATTERN Cited by 1 source
Expand-and-contract schema migration¶
Pattern¶
When a schema change is irreversible (e.g. dropping a column, renaming a table), split the work across multiple migrations deployed in separate cycles:
- Expand — add the new structure (new columns, new table) alongside the old. Both old and new exist simultaneously; old readers continue working against the old shape.
- Populate — backfill the new structure from the old data. Dual-write if the system is live.
- Swap readers — migrate application code to read from the new structure.
- Contract — after a deployment cycle confirms no live readers reference the old shape, drop the old columns/tables in a subsequent migration.
This decomposition ensures each individual migration is backward-compatible and independently reversible — if the expand migration fails, the rollback is trivial (drop the new columns); the old shape was never touched.
Canonical framing¶
"It's better to split irreversible work across migrations. For example a migration that adds new columns and drops the source column in one shot makes rollback harder than they need to be, so using the expand first and contract later strategy provides many more options after a deploy cycle confirms no live readers reference it."
(Source: sources/2026-06-05-databricks-enabling-evolutionary-database-development-database-branchin)
Relationship to the database refactoring catalog¶
The 2006 Refactoring Databases book (Sadalage & Ambler) names 70+ refactorings with explicit transition mechanics. Many of them are instances of expand-and-contract:
- Split Column — add new columns (expand), populate from the original (backfill), swap readers, drop original (contract).
- Rename Column — add new-name column (expand), dual-write + backfill, swap readers, drop old-name (contract).
- Move Column — add column on target table (expand), populate, swap, drop from source (contract).
The pattern is the meta-strategy that connects individual refactorings to safe deployment under continuous delivery.
Anti-patterns¶
- Big-bang migration — expand and contract in a single migration script. Rollback requires replaying the inverse, which may be lossy.
- Unbounded contract deferral — expanding but never contracting. Accumulates dead columns, confuses future developers, inflates storage.
Seen in¶
- systems/lakebase — the Evolutionary Database Development playbook explicitly names expand-and-contract as the canonical strategy for Lakebase branching workflows.
- Zero-downtime deployment practices at GitHub, Stripe, and Shopify all use variants of this pattern for schema changes against live databases.
Related¶
- concepts/evolutionary-database-design — the methodology that expand-and-contract serves.
- concepts/idempotent-migration — each expand/contract step must be idempotent.
- patterns/ci-ephemeral-database-branch-with-schema-diff-comment — CI validates each step in isolation on an ephemeral branch.