Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Backward-Compatible Migrations
HLD

Backward-Compatible Migrations

Migrations that never break the version running next to them — the N/N+1 contract for schemas.

The Compatibility Contract

 during any deploy window, TWO code versions hit ONE schema:

 [v1 pods]──┐
            ├──►[schema S']   ← who breaks?
 [v2 pods]──┘

 BACKWARD-COMPATIBLE migration rules keep both alive:

 SCHEMA changes that are safe mid-roll:
 ✓ ADD nullable column / column with default
 ✓ ADD new table/index (CONCURRENTLY!)
 ✓ WIDEN constraints gradually (NOT NULL only after backfill)

 SCHEMA changes that break a neighbor:
 ✗ DROP/RENAME columns v1 reads
 ✗ ADD NOT NULL without default (v1 inserts fail!)
 ✗ TIGHTEN check constraints against existing patterns
 ✗ CHANGE column types/meanings

 the mental model: every migration must leave the schema
 serving the PREVIOUS release perfectly.

The Multi-Release Pattern

 breaking changes decompose across RELEASE boundaries:

 GOAL: rename users.phone → phone_number

 RELEASE N:   add phone_number nullable; app writes BOTH
 RELEASE N+1: backfill; app READS new column only
 RELEASE N+2: stop writing old column
 RELEASE N+3: drop old column (census confirmed zero readers)

 each release deploys independently and safely;
 rollback at ANY point stays functional because
 every intermediate state served two versions.

 this is expand-contract STRETCHED across releases —
 slower but bulletproof for high-stakes tables.

Enforcement, Not Vibes

 compatibility violations slip through review constantly.
 mechanical checks:

 □ CI LINTERS on migrations: forbid DROP/RENAME/NOT-NULL-
   without-default in normal migrations (require explicit
   escape-hatch flags + review)
 □ CONTRACT TEST matrix: previous-release app version ×
   new schema — run in CI against migrated staging clone
 □ COLUMN-LEVEL USAGE tracking: which services SELECT/INSERT
   which columns (audit logs / query analysis) → safe-drop census
 □ DEPLOY TOOLS aware of DB state: block deploys when
   pending incompatible migration pairs detected

 culture line for reviews:
 "what does the PREVIOUS version experience during this
  migration's entire window?" — unanswerable = not ready.
ViolationProduction symptom
dropped column earlyv1 pods error-burst mid-roll
NOT NULL added pre-backfillinserts fail on old instances
renamed field in API+schema same daymobile clients break for weeks
index added blockingwrite stall during “simple” deploy

Interview Framing

“How do you ensure rolling deploys never break on schema changes?” scored shape: the two-versions-one-schema framing first, safe/unsafe change lists, multi-release decomposition walked through one concrete rename, CI enforcement mechanisms named (linters+contract-matrix). This question tests whether your team treats compatibility as an ENFORCED CONTRACT or reviewer folklore — mechanics beat intentions.

My Private Notes

Notes are auto-saved locally to this device.