All articles

PostgreSQL 14 is going EOL: upgrading to 17 (or 18) with minimal downtime

4 min read
PostgreSQLDatabasesMigrationDevOps

PostgreSQL 14 reaches end of life on 12 November 2026 — after that, no more security patches or bug fixes from the project. PostgreSQL EOLs are quiet compared to a Windows deadline, which is exactly why they get missed: the database keeps working, so nobody plans the upgrade until an auditor, an insurer, or a CVE forces it. Here is how to do it deliberately, and how to choose an upgrade method by how much downtime you can actually afford.

What "upgrade" means here

Minor updates (14.11 → 14.12) are trivial — install and restart. This article is about the major version jump (14 → 17, or 18 if you want the latest), which changes the on-disk format and therefore needs a real migration, not a package update. The good news: the choice of *how* is well-trodden, and it comes down to your tolerance for downtime.

The three methods, by downtime

  • Dump and restore (`pg_dump` / `pg_restore`). The simplest and most robust: dump the old cluster, restore into a fresh new-version cluster. Downtime scales with data size, so it is fine for small databases and a poor fit for large or busy ones. It is also the cleanest way to leave bloat and old cruft behind.
  • `pg_upgrade`. Upgrades the existing data directory in place, and with `--link` (hard-linking the data files) it is fast — minutes, largely independent of data size — because it does not copy the data. The trade-off is that you cannot easily roll back a `--link` upgrade once started, so the tested backup beforehand is mandatory.
  • Logical replication. The near-zero-downtime path: stand up the new version alongside the old, replicate changes into it live, let it catch up, then cut over with a brief switch of the application. It is the most moving parts and the most setup, and it is the right answer when the database cannot take a maintenance window — the same live-cutover thinking behind a good Patroni failover plan.

The honest rule: small database, take the window and use `pg_upgrade` (or dump/restore). Large and busy with no window, invest in logical replication. Do not reach for the complex method out of habit when a five-minute `pg_upgrade` would do.

The things that actually bite

The upgrade mechanism is rarely the problem. These are:

  • Extensions. PostGIS, pg_stat_statements, TimescaleDB, pgvector and friends have their own version compatibility, and a `pg_upgrade` will refuse to proceed if an extension is not available on the target. Inventory and match every extension on the new version *before* you start — this is the most common cause of a stalled upgrade.
  • Deprecated and changed behaviour. Each major version removes or changes something — configuration parameters, default settings, occasionally query behaviour. Read the release notes for every version you are jumping over (14 → 15 → 16 → 17), not just the destination.
  • Connection poolers and replicas. PgBouncer, replicas, and any HA layer need re-pointing or rebuilding around the new primary; a physical standby cannot span a major-version upgrade and must be re-seeded.
  • Post-upgrade statistics. `pg_upgrade` does not carry over optimiser statistics — run `ANALYZE` immediately after, or the first hours on the new version are needlessly slow and someone declares the upgrade "broke performance."

Rehearse on a copy, then cut over

Restore a recent backup onto a scratch host, run the exact upgrade you plan, point a copy of the application at it, and check the queries and the extensions. Time it. Only when the rehearsal is boring do you schedule the real cutover — with a fresh backup taken and, for anything but a trivial database, a rollback path defined. Migrations off other engines are harder still; if you are also weighing a platform change, our SQL Server to PostgreSQL notes cover what breaks there.

What we do

We run PostgreSQL for clients end to end — design, migration and 24/7 support — and version EOLs are routine work, not emergencies. We inventory your extensions and replication topology, pick the upgrade method that fits your downtime budget, rehearse it on a copy, and run the cutover with a tested backup and a rollback. PostgreSQL 14's EOL is a fixed date on the calendar; the point of planning now is that the upgrade is a boring maintenance window instead of a scramble after the support ran out.

PostgreSQL 14 on the clock?

We run PostgreSQL end to end — we will inventory your extensions and replication, pick the upgrade method that fits your downtime budget, rehearse it on a copy, and cut over with a tested backup and a rollback.