Code Reference

Migrations Ops

Postgres · Reference cheat sheet

Migrations Ops

Postgres · Reference cheat sheet


📋 Overview

Schema changes in production need expand/contract discipline, lock awareness, and backwards-compatible deploys. Tooling (Flyway, Liquibase, Prisma, Alembic, golang-migrate) applies SQL — ops principles stay the same.

🔧 Core concepts

PracticeWhy
Expand/contractAvoid dual-write downtime
Backwards compatible migrationsOld app + new schema coexist
Short transactionsReduce lock duration
CONCURRENTLY indexesAvoid long write locks
Migration history tableIdempotent applies
Risky DDLSafer approach
Rewrite huge table in placeAdd column → backfill → switch
ALTER TYPE recreatesAdd new column/type carefully
Long ALTER TABLE locksCheck pg_locks / schedule window

💡 Examples

Add nullable column (safe):

ALTER TABLE users ADD COLUMN locale text;

Backfill in batches (app job):

UPDATE users SET locale = 'en' WHERE locale IS NULL AND id IN (
  SELECT id FROM users WHERE locale IS NULL ORDER BY id LIMIT 1000
);

Online index:

CREATE INDEX CONCURRENTLY users_locale_idx ON users (locale);

⚠️ Pitfalls

  • Running CREATE INDEX without CONCURRENTLY on large tables locks writes.
  • Multi-statement migrations without transactions (or with ones that can't run in a txn, like concurrent index) need clear tool support.
  • Ignoring failed mid-migration state leaves environments drifted.

On this page