// the find
xataio/pgroll
PostgreSQL zero-downtime migrations made easy
pgroll solves the genuinely hard problem of running schema migrations against live Postgres without downtime. It does this by maintaining two schema versions simultaneously via views, with triggers propagating writes between old and new columns during the transition window. Aimed at teams that have been burned by ALTER TABLE locking their production database at 2am.
The expand/contract implementation is the real thing, not a thin wrapper — it creates shadow columns, installs bidirectional triggers, and only renames on completion, so rollback is actually instant rather than aspirationally instant. The sql2pgroll converter lets teams migrate existing plain SQL migration files without rewriting everything from scratch. Benchmarks are tracked per-commit against multiple Postgres versions (14 through 18), so write amplification from triggers isn't just hand-waved away. The baseline command handles brownfield databases, which is table stakes for any team that can't start from a clean schema.
The JSON/YAML migration DSL is a significant mental overhead — you're learning a new schema language on top of SQL, and the raw_sql escape hatch exists precisely because the DSL doesn't cover everything. The dual-schema view layer adds latency to every query during an active migration window; the benchmarks show the numbers but don't tell you what a 30% write slowdown means for your p99 at scale. Trigger-based backfill means large tables take real time to migrate, and there's no obvious progress visibility beyond log output. Teams using connection poolers like PgBouncer in transaction mode will hit friction because search_path must be set per-connection, which doesn't survive pool reuse.