A small schema migration CLI
A single static binary that applies numbered SQL migrations to Postgres, checksums what it has applied, and takes an advisory lock so rolling deploys do not race.
- Role
- Author and maintainer
- Client
- Self-directed
- Year
- 2025
A command line tool for applying SQL migrations to Postgres. It exists because I kept rewriting the same fifty lines of shell in every project, and because the off-the-shelf options either wanted a runtime I did not have or insisted on owning the schema.
Design
One directory of numbered .sql files, one table recording what has been applied, and a checksum on every applied file so an edited migration is an error rather than a surprise. There is no down-migration story: reversals are written as new files, which is what happens in practice anyway.
$ mig status --url "$DATABASE_URL"
0001_init.sql applied 2025-08-14T09:12:04Z
0002_add_ledger.sql applied 2025-08-21T17:40:11Z
0003_backfill_totals.sql pending
$ mig up --url "$DATABASE_URL"
0003_backfill_totals.sql applied in 812ms
Each migration runs inside a transaction, and the run as a whole holds a session advisory lock, so two instances starting at once during a rolling deploy is safe rather than a race. The binary is statically linked and around four megabytes, so it drops into a container image without dragging an interpreter along.
It is deliberately small and I intend to keep it that way. The interesting work in migrations is not the tool.