Run database migrations on startup (with a guard)

86
0

I generally prefer running migrations in a separate release step, but for smaller deployments it’s sometimes pragmatic to run them at startup. The failure mode to avoid is “every instance runs migrations at once.” The pattern here uses Postgres advisory locks: only one instance can hold the lock, so only one instance performs migrations. Everyone else waits (or skips) and then continues booting. This keeps startup safe during rolling deploys and prevents two migrators from colliding. I still keep migrations idempotent and I make startup fail if migrations fail, because a partially migrated schema is worse than downtime. In production, you’ll want observability around migration duration and a maximum lock wait so the service doesn’t hang forever. But as a baseline, advisory locks make the approach much safer.