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
How to Run Migrations as a Separate CI Job With the Right CredsRun migrations in a dedicated CI job with a scoped migration role and secret, separate from the app deploy, s…
How to Run Flyway and Liquibase Migrations in CIRun Flyway and Liquibase migrations in a CI/CD pipeline with their migrate and status commands, the standard…