Expand: add the new column (or table) with a DEFAULT or as nullable; this is an immediate metadata change in PostgreSQL 11+ for columns with non-volatile defaults
Deploy application code that writes to both old and new columns simultaneously while reading from the old column only
Backfill the new column in small batches (UPDATE ... WHERE id BETWEEN x AND y) to avoid long-running transactions and lock contention
Switch reads to the new column in the application; verify correctness with shadow reads if needed
Contract: once all reads and writes go through the new column, remove the old column or constraint in a separate migration
Use LOCK TIMEOUT and statement_timeout on the ALTER TABLE to abort rather than queue if it cannot acquire the lock promptly
Known gotchas
Adding a column with a volatile DEFAULT (e.g., now()) or changing a column type still rewrites the table in all PostgreSQL versions; plan for an online schema change tool or a maintenance window for those cases
NOT NULL constraints added without a DEFAULT cause a full table scan for validation; use the two-step approach: add as nullable, backfill, then add the constraint as NOT VALID followed by VALIDATE CONSTRAINT in a separate transaction
Indexes created with CREATE INDEX CONCURRENTLY can fail silently leaving an INVALID index; always check pg_indexes or \d after creation and drop-recreate invalid indexes
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp