Adding a column is easy. Removing one, renaming it, or changing its type while two versions of your application are live is where teams get hurt. Here is the sequence we recommend, and the two places it still goes wrong.
During a blue-green deploy both versions run against the same database. Every migration must therefore be compatible with the code that is already running and the code that is about to run. That means no destructive step ships with the deploy that needs it.
Even ALTER TABLE ... ADD COLUMN with a default takes an ACCESS EXCLUSIVE lock briefly. On a busy table behind a connection pool, a query already holding a lock will make your migration queue — and every request behind it. Always set lock_timeout to a couple of seconds and retry, rather than letting the migration wait indefinitely.
A single UPDATE across ten million rows holds row locks, bloats the table and hands your replicas a monster WAL segment to replay. Batch it, commit between batches, and watch replay_lag while it runs.
Norvik migration runs apply lock_timeout and statement_timeout by default, refuse destructive statements unless the change is explicitly marked as a contract step, and pause automatically when replica replay lag crosses a threshold you set per project.