Skip to content
Latchkey

How to Prevent Concurrent Migrations With an Advisory Lock

Two deploys running migrations at once can conflict; a session advisory lock ensures only one migrator proceeds while others wait or fail.

Parallel pipelines can both try to migrate the same database. A Postgres advisory lock gives a cheap mutex: the first migrator acquires it, the rest wait. Many tools do this automatically; you can also wrap your own scripts with pg_advisory_lock.

Wrap DDL in an advisory lock

migration.sql
-- blocks a second migrator until the first releases
SELECT pg_advisory_lock(72111);
ALTER TABLE reports ADD COLUMN archived boolean DEFAULT false;
SELECT pg_advisory_unlock(72111);

Non-blocking variant for CI

Terminal
-- exit early if another runner is already migrating
psql "$DATABASE_URL" -tAc "SELECT pg_try_advisory_lock(72111)" \
  | grep -q t || { echo "migration already running"; exit 0; }

Gotchas

  • A session-level advisory lock releases when the connection closes; hold it for the whole migration.
  • Rails and Flyway take a migration lock automatically, so double-locking is usually unnecessary there.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →