← Engineering Dispatches / Cloud & DevOps
Zero-Downtime PostgreSQL Major Version Upgrades: A Step-by-Step Guide with Logical Replication and pg_upgrade
By Aman Aslam · 13 min read read
Architectural Takeaways
- Logical Replication streams row-level changes (DML) across different PostgreSQL major versions without locking tables or interrupting active transactions.
- Sequences do not synchronize automatically over logical replication; export sequence values immediately prior to the cutover window.
- Always configure reverse replication from the new target cluster back to the old cluster during switchover to allow instantaneous rollback without data loss.
1. In-Place pg_upgrade vs Logical Replication Blue-Green
`pg_upgrade --link` is fast but requires a complete database shutdown during execution and offers no instant rollback if queries perform unexpectedly. Logical replication creates a decoupled Blue-Green environment where the new cluster can be thoroughly benchmarked under read traffic before switching primary traffic.
2. Step-by-Step Publication & Subscription Configuration
On the source database, we set `wal_level = logical` and create a publication encompassing all application tables. The target database subscribes to the source, copying initial table states and streaming incremental changes.
3. Handling Sequences, Triggers & DDL Sync
Because logical replication does not replicate DDL schema migrations or sequence updates (`nextval()`), sequences must be queried on the source and updated on the target using `setval()` right before routing application traffic.
4. The 30-Second Cutover Runbook & Zero-Risk Rollback
During the cutover window: 1) Pause PgBouncer connections, 2) Sync final sequence values, 3) Re-enable triggers and foreign keys on target, 4) Point PgBouncer to the PostgreSQL 17 target cluster, 5) Resume traffic. Total downtime: under 20 seconds.
Read more technical guides on our Dispatches Index →