Your migration hung for 20 minutes: ALTER TABLE is waiting on a lock from a transaction someone forgot
Problem
A routine ALTER TABLE orders ADD COLUMN tenant_id uuid — fast on staging — hung in prod for 20 minutes, and then every request touching orders piled up behind it:
ERROR: canceling statement due to statement timeout
CONTEXT: while ALTER TABLE orders ADD COLUMN tenant_id uuid, waiting for AccessExclusiveLockThe app's request timeout eventually fired, the migration kept waiting, and the deployment was rolled back with the table locked by nothing.
Root cause
ALTER TABLE needs AccessExclusiveLock on the whole table. It queues behind long-running transactions (an idle-in-transaction psql session, a stuck batch job, a forgotten BEGIN from a dashboard query) and, once queued, everything else queues behind it — even fast SELECTs that would have taken 2ms. The migration was the victim of a transaction that should have ended minutes earlier; the outage was the queue.
SELECT pid, state, xact_start, now() - xact_start AS age, query
FROM pg_stat_activity
WHERE state <> 'idle'
… 2 more lines in the fix🔒 the fix — including 3 code blocks — is members-only. $1/mo unlocks everything.