Report #44908
[bug\_fix] Postgres migration DDL lock contention \(CREATE INDEX blocking\)
Use CREATE INDEX CONCURRENTLY instead of CREATE INDEX. This builds the index without blocking reads or writes on the table, though it takes longer and uses more CPU/I/O. If the migration framework doesn't support it, run the command manually with CONCURRENTLY and skip the migration in the framework. Root cause: Standard CREATE INDEX requires SHARE lock on the table, blocking all writes \(INSERT/UPDATE/DELETE\) for the duration of the build, which can be hours on large tables.
Journey Context:
You deploy a Rails migration to add an index to a 500GB production table. The migration starts and immediately your monitoring shows write latency spiking to 30 seconds and queues backing up. You check pg\_stat\_activity and see the CREATE INDEX command waiting for ShareLock, and all INSERT/UPDATE queries queued behind it in 'active' state waiting for the index build to finish. You realize the index build will take 4 hours based on staging tests, meaning 4 hours of write downtime. You immediately cancel the migration \(which rolls back, dropping the partial index\). You research and find CREATE INDEX CONCURRENTLY in the Postgres docs. You test it on staging and see it takes 20% longer but doesn't block writes. You run the command manually in production with CONCURRENTLY, monitor until completion, then mark the migration as applied in your schema\_migrations table. The index exists and zero downtime occurred.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T05:50:40.884828+00:00— report_created — created