Science, Technology & The Future
PostgreSQL 14 reaches end of life on 12 November 2026: rehearse the upgrade on a copy first
PostgreSQL 14 gets its final release on 12 November 2026, and after that it is unsupported. Here is what that means, how to find your version, and how to rehearse the upgrade on a copy first, in the commands PostgreSQL's own documentation gives.
What end of life means
PostgreSQL's versioning policy says each major version receives bug fixes and, if need be, security fixes in minor releases. After its support period, "a final minor version will be released and the software will then be unsupported (end-of-life)." The table on that page lists the final release of version 14 as November 12, 2026. After it, there are no more fixes for 14.
The page recommends that users "always run the current minor release associated with their major version"; today its table lists 14.24 as the current minor of 14. If your database is managed, your provider's own upgrade path and dates apply.
Read your version
Ask the server, with either of:
SELECT version();
SHOW server_version;
From PostgreSQL 10 on, the major version is the first part of the number, so 14.24 is major version 14. The newest major version today is 18: the documentation marks it Current, and the table lists 18.6 as its current minor and November 14, 2030 as its final release. The documentation lists 19 only as a development version.
A major upgrade needs a dump and reload or pg_upgrade. You can go from one major version to another without stopping at those between, but the policy recommends reading the release notes of every major version in between first.
Rehearse on a copy first
Do not make production the first place the upgrade runs. Restore last night's backup into a throwaway server of your production major version, by the method in our restore drill piece, and upgrade that copy. Time every part: the restore, the check, the upgrade and the steps after it. Those times are what you plan downtime from.
Check first, then run
Install the new server's binaries; pg_upgrade is part of a default installation. Initialize the new cluster with initdb, using flags compatible with the old cluster; there is no need to start it. Install the extension shared object files that match the new server, but do not run CREATE EXTENSION for them: their definitions are copied from the old cluster. Always run the pg_upgrade of the new server, not the old one.
Then check, and change nothing:
pg_upgrade --check --link -b oldbindir -B newbindir -d oldconfigdir -D newconfigdir
oldbindir, newbindir, oldconfigdir and newconfigdir are the synopsis's names for the old and new executable and configuration directories. --check checks the clusters and changes no data, even with the old server still running; then the old and new port numbers must differ (-p, -P). It also outlines any manual adjustments you will need after the upgrade. Give it the mode option of the real run (--link here) so the mode-specific checks run, and make the current directory writable.
Once the check is clean, stop both servers and run the same command without --check:
pg_upgrade --link -b oldbindir -B newbindir -d oldconfigdir -D newconfigdir
No one should be using the clusters during the upgrade. pg_upgrade connects to both servers several times, so you may set authentication to peer in pg_hba.conf or use a ~/.pgpass file. These flags are from the PostgreSQL 18 page: if you upgrade to another major version, read that version's page.
Copy, link or clone
- Copy, the default (
--copy): the files are copied to the new cluster. The old cluster is left unmodified and can be restarted. - Link (
--link,-k): hard links instead of copying. It is much faster and uses less disk space, but once the new cluster is started you cannot use the old one: they share files, so the old cluster must be restored from backup. Both data directories must be in the same file system. - Clone (
--clone): the same speed and disk space advantages, with the old cluster left usable. It needs the same file system and works only on some: Linux (kernel 4.5 or later) with Btrfs, or XFS made with reflink support, and macOS with APFS. Where it is unsupported, the run errors.
The documentation also describes --swap, which destructively modifies the old cluster once the file transfer begins. With link or swap, your proven backup is the only way back.
After the upgrade
Restore pg_hba.conf if you changed it, then start the new server. If post-upgrade processing is needed, pg_upgrade warns and writes script files; run each one:
psql --username=postgres --file=script.sql postgres
The scripts can run in any order and be deleted once run. Do not access tables the rebuild scripts reference until they finish: the results could be wrong or slow. If extension updates are available, pg_upgrade reports it and creates a script to run later.
Unless you pass --no-statistics, pg_upgrade transfers most optimizer statistics, but not all: not those from CREATE STATISTICS, nor an extension's custom ones, nor those of the cumulative statistics system. So run:
vacuumdb --all --analyze-in-stages --missing-stats-only
vacuumdb --all --analyze-only
The first quickly builds minimal statistics for relations that have none; the second updates the cumulative statistics that trigger vacuum and analyze. --jobs speeds up both. Delete the old cluster only when you are satisfied, with the script pg_upgrade names when it completes.
The order a real upgrade follows
1. Backup proven: restored into a throwaway server and compared, table by table. 2. Rehearsal timed, on a copy made from that backup. 3. pg_upgrade --check clean. 4. Downtime agreed with the people who use the application. 5. The upgrade itself. 6. The post-upgrade steps: scripts, extension updates, statistics. 7. The application checked against the upgraded database.
What we run
We run PostgreSQL 18.6 in production, and our restore drill has passed every Sunday since 4 October: our latest results.
Nexidy can rehearse the same upgrade on a copy of your database: read-only on production until you approve the change, every step written down for your team, and the report signed off by Hamed Kabir.