TABLE OF CONTENTS
- •Plan your PostgreSQL 14 upgrade with a senior team
- •At a Glance: PostgreSQL 14 End of Life
- •What Does End of Life Mean for Your Business?
- •Start with an Inventory: Which Version Are You Running?
- •Target Version: PostgreSQL 17 or 18?
- •Which Upgrade Method Fits You?
- •If You Run on Azure or Amazon RDS
- •Pre-Upgrade Checklist
- •Method 1: pg_upgrade from 14 to 18
- •1. Create the new cluster
- •2. Run the compatibility check
- •3. Stop PostgreSQL 14 and upgrade
- •4. Start PostgreSQL 18 and finish the job
- •Method 2: Near-Zero Downtime with Logical Replication
- •1. Create a publication on PostgreSQL 14
- •2. Copy roles and schema to PostgreSQL 18
- •3. Create a subscription on PostgreSQL 18
- •4. Cut over
- •Method 3: pg_dump and pg_restore
- •Collation, glibc and REINDEX
- •Rollback Plan
- •Post-Upgrade Checks
- •When Should You Bring in an Expert?
- •Frequently Asked Questions
- •Sources
- •Leave PostgreSQL 14 before support ends
PostgreSQL 14 reaches end of life on November 12, 2026. Your servers will keep running after that date, but newly discovered security vulnerabilities and bugs will no longer be fixed for version 14. We recommend planning the upgrade now and choosing PostgreSQL 18 as the target.
This guide is written for two readers: the IT managers who make the decision and the technical teams who carry out the upgrade. The first sections summarize what end of life means for the business, how to choose the target version and how the upgrade methods compare. The later sections contain tested steps for pg_upgrade, logical replication and dump/restore. We ran the commands on PostgreSQL 14.24 and 18.6.
Plan your PostgreSQL 14 upgrade with a senior team
Aryasoft reviews your PostgreSQL 14 servers for extensions, collations, replication and downtime limits, then agrees the target version, the upgrade method and the rollback plan with you.
At a Glance: PostgreSQL 14 End of Life
| Topic | Summary |
|---|---|
| End of life | November 12, 2026. The 14.x minor release published that day is the last update for PostgreSQL 14. |
| What happens next? | Servers keep running, but no more security or bug fixes are released. |
| Recommended target | PostgreSQL 18 (supported until November 2030). PostgreSQL 17 if an extension or application requires it. |
| Intermediate versions needed? | No. You can go straight from 14 to 17 or 18. |
| Fastest method | pg_upgrade --link on the same server |
| Shortest downtime | Logical replication to a new server (a few minutes at cutover) |
| Azure and AWS | Paid extended support is available: on Azure from February 1, 2027, on Amazon RDS from February 28, 2027. |
What Does End of Life Mean for Your Business?
The PostgreSQL community supports each major version for five years from its first release. For PostgreSQL 14, released on September 30, 2021, that period ends with the final minor release on November 12, 2026.
End of life is not a shutdown date; no server will stop on the morning of November 13. What changes is the maintenance status of the version:
| Area | After November 12, 2026 |
|---|---|
| Server operation | Unaffected. |
| Security vulnerabilities | New vulnerabilities are fixed in 15, 16, 17 and 18, not in 14. |
| Bug fixes | No fixes are released for 14, including bugs that can cause data corruption. |
| Extensions and drivers | Vendors drop unsupported versions from their new releases over time. |
| Audit and compliance | Unsupported software is reported as a finding in information security audits. |
| Cloud services | Azure and Amazon RDS move to a paid extended support period. |
In short, every month on PostgreSQL 14 accumulates risk you can no longer patch away. The earlier the upgrade is planned, the calmer the project runs.
Start with an Inventory: Which Version Are You Running?
Run the two commands below on every server. For comparisons in scripts, server_version_num is more convenient: 140024, for example, means 14.24.
SELECT version();
SHOW server_version_num;
If you run a 14.x release older than 14.24, move to the latest minor release first. A minor update needs no dump or pg_upgrade and lets you start the major upgrade from a system free of known bugs.
Target Version: PostgreSQL 17 or 18?
You can move from 14 directly to either version; there is no need to step through 15 and 16. These are the differences that matter for the decision:
| PostgreSQL 17 | PostgreSQL 18 | |
|---|---|---|
| First release | September 26, 2024 | September 25, 2025 |
| Community support | Until November 8, 2029 | Until November 14, 2030 |
| Current minor release (October 2026) | 17.11 | 18.6 |
| pg_upgrade and statistics | Optimizer statistics are not transferred; ANALYZE is needed before production load. | Most statistics are transferred. Only extended statistics (CREATE STATISTICS) must be rebuilt. |
| pg_upgrade modes | –link, –clone, –copy, –copy-file-range | Plus –swap, –no-statistics and parallel checks (–jobs) |
| Defaults to review | Maintenance operations run with a safe search_path. | Data checksums on by default, MD5 passwords deprecated, asynchronous I/O (io_method). |
Our recommendation is PostgreSQL 18. It is supported for one more year, and because statistics are transferred, the system returns to normal performance faster after the upgrade. If an extension you use, your application vendor or your cloud provider does not support 18 yet, PostgreSQL 17 is a safe alternative.
We see no reason to wait for PostgreSQL 19. Its first release candidate (RC1) came out on October 15, 2026, and general availability is planned for November 19, 2026. Extensions, drivers and tools usually take a few months to support a new major version.
Whichever target you choose, read the “Migration to Version” section of the release notes for every version you skip. The change that most often surprises applications coming from 14 is in PostgreSQL 15: in new databases, the PUBLIC role can no longer create objects in the public schema. Upgraded databases keep their existing privileges; the difference appears in databases created after the upgrade.
Which Upgrade Method Fits You?
Three questions decide the method: How much downtime is acceptable? Is extra disk or a new server available? How will you roll back if something goes wrong?
| Method | Downtime | Extra resources | Rollback | Best fit |
|---|---|---|---|---|
| pg_upgrade –link | Short; data files are not copied | Very little (same file system required) | Only from backup once the new cluster has started | Large databases staying on the same server, with a tested backup |
| pg_upgrade –clone | Short, close to link mode | Only as much as changed blocks | The old cluster stays usable | File systems with reflink support (Btrfs, XFS with reflink) |
| pg_upgrade –copy | Grows with data size | A full copy of the data | The old cluster is untouched | Small and medium databases with enough free disk |
| pg_dump / pg_restore | Longest; writes are stopped during the process | Dump file and a new cluster | The source system stays as it is | Small databases, new hardware or operating system |
| Logical replication | Only at cutover, a few minutes | A second server | The old server runs until you shut it down | Systems with very little tolerance for downtime, new hardware or a move to the cloud |
| Cloud service upgrade | No access during the operation | Managed by the provider | Snapshot or service backup | Azure Database for PostgreSQL and Amazon RDS |
In practice the choice usually comes down to this:
- If you are staying on the same server and a few minutes to an hour of downtime is acceptable: pg_upgrade.
- If downtime is limited to minutes or you combine the upgrade with a move to new hardware: logical replication.
- If the database is small and you want to turn the upgrade into a clean-up project: dump/restore.
PostgreSQL 18 also adds the --swap mode. It moves the old data directories into the new cluster and can be the fastest option for clusters with many tables and indexes. As with link mode, it is not safe to start the old cluster once the file transfer has begun.
If You Run on Azure or Amazon RDS
On managed services the provider runs the upgrade, but the schedule and the cost are your responsibility.
| Azure Database for PostgreSQL (flexible server) | Amazon RDS for PostgreSQL | |
|---|---|---|
| Upgrade method | In-place upgrade based on pg_upgrade; can skip versions | You start the major version upgrade yourself |
| Extended support | February 1, 2027 – November 11, 2029 | Standard support ends February 28, 2027; extended support runs until February 28, 2030 |
| Cost | Paid; servers on an unsupported version are enrolled automatically | Paid; Multi-AZ standby instances are charged too |
| Watch out for | Read replicas must be deleted before and recreated after the upgrade; ANALYZE is needed afterwards | Most extensions are not upgraded with the engine and must be planned separately |
Azure runs a precheck before the upgrade and takes an implicit backup to roll back to if it fails. Amazon RDS lists 17.11 and 18.6 as direct targets for PostgreSQL 14.24.
Note
Extended support does not solve the problem; it only buys time. It costs extra on both Azure and AWS and ends on a fixed date. Use it to finish a planned upgrade comfortably, not to postpone one.
Pre-Upgrade Checklist
| Check | Why it matters |
|---|---|
| Inventory | List servers, databases, sizes, collations, extensions and replication slots. The whole plan rests on this list. |
| Extensions | Confirm that every extension you use is available for the target version and platform. On Azure some extensions can block an in-place upgrade. |
| pg_upgrade –check | Reports blockers on the running 14 server without changing anything: reg* columns, prepared transactions, missing libraries. |
| Collation and OS | If the upgrade also moves you to a new glibc version, text indexes must be rebuilt. |
| Authentication | Find roles still using MD5 passwords; PostgreSQL 18 has deprecated this method. |
| Backup | Take a full backup and prove that it restores. In link and swap modes this is your only way back. |
| Rehearsal | Restore production data to a test server, run the whole upgrade, time it and run the application tests. |
The queries below give you the core of the inventory. Run the extension query in every database.
-- Databases, size and collation
SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size, datcollate
FROM pg_database WHERE datallowconn ORDER BY pg_database_size(datname) DESC;
-- Installed extensions (run in every database)
SELECT extname, extversion FROM pg_extension ORDER BY extname;
-- Items pg_upgrade or a cutover cares about
SELECT count(*) AS prepared_xacts FROM pg_prepared_xacts;
SELECT slot_name, slot_type, active FROM pg_replication_slots;
SHOW data_checksums;
-- Roles still using MD5 password hashes
SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%';
-- Tables without a primary key (matter for logical replication)
SELECT c.oid::regclass AS table_without_pk
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE i.indrelid = c.oid AND i.indisprimary);
Method 1: pg_upgrade from 14 to 18
The examples follow the Debian and Ubuntu package layout of apt.postgresql.org, where each version’s programs live under /usr/lib/postgresql/<version>/bin. Install the PostgreSQL 18 packages alongside 14 and run every command as the postgres user from a directory that user can write to.
1. Create the new cluster
The new cluster must use the same locale and encoding as the old one. One detail matters: PostgreSQL 18 enables data checksums by default, while pg_upgrade requires both clusters to have the same setting. A 14 cluster created with default settings has checksums off, so use --no-data-checksums. Otherwise the check stops with “old cluster does not use data checksums but the new one does”.
OLD=/usr/lib/postgresql/14/bin
NEW=/usr/lib/postgresql/18/bin
cd /var/lib/postgresql/upg
$NEW/initdb -D ../pg18 -U postgres --locale=en_US.UTF-8 -E UTF8 --no-data-checksums
2. Run the compatibility check
The check can run while PostgreSQL 14 is serving traffic. Pass the mode you will use for the real upgrade (such as --link) here as well.
$NEW/pg_upgrade -b $OLD -B $NEW -d ../pg14 -D ../pg18 -p 5414 -P 5418 --check --link
In our test the first check stopped at “Checking for reg* data types in user tables” and wrote the offending column to tables_using_reg.txt under pg_upgrade_output.d. These data types store system identifiers (OIDs) that pg_upgrade cannot preserve. After the column was changed to text on the 14 server, the check finished with “Clusters are compatible”.
3. Stop PostgreSQL 14 and upgrade
$OLD/pg_ctl -D ../pg14 -w stop -m fast
$NEW/pg_upgrade -b $OLD -B $NEW -d ../pg14 -D ../pg18 -p 5414 -P 5418 --link --jobs 2
The run ends with “Upgrade Complete”. If newer extension versions exist, pg_upgrade writes an update_extensions.sql file, and it creates a delete_old_cluster.sh script to remove the old cluster. Do not run that script until the new cluster has passed every check and a fresh backup has been taken.
Warning
In link mode the old and new clusters share the same data files. Once PostgreSQL 18 has started, you can no longer safely go back to the 14 cluster; the only way back is a restore from backup. Take the backup before step 3 and confirm that it restores.
4. Start PostgreSQL 18 and finish the job
pg_upgrade does not move configuration files. Before pointing applications at the new cluster, carry over pg_hba.conf and the postgresql.conf settings you need. Then start the server, update extensions and create the missing statistics:
$NEW/pg_ctl -D ../pg18 -o "-p 5432" -l ../pg18.log -w start
psql -U postgres -f update_extensions.sql
$NEW/vacuumdb -U postgres --all --analyze-in-stages --missing-stats-only
$NEW/vacuumdb -U postgres --all --analyze-only --jobs 2
In our test PostgreSQL 18 already had the table’s statistics before any ANALYZE had run, and the generated script updated pgcrypto from 1.3 to 1.4. The cluster kept data_checksums = off, as on 14.
If you run standby servers with streaming replication, the pg_upgrade documentation explains step by step how to upgrade them with rsync after the primary. Plan this part with particular care: a mistake here means rebuilding the standbys from scratch.
Method 2: Near-Zero Downtime with Logical Replication
Logical replication copies the data to a new PostgreSQL 18 server and keeps streaming changes until cutover. Because the old server keeps running throughout, downtime is limited to the cutover itself.
Before you start, set wal_level = logical on the 14 server (requires a restart) and allow the replication user in pg_hba.conf.
1. Create a publication on PostgreSQL 14
CREATE ROLE repl_user WITH LOGIN REPLICATION PASSWORD 'change_me';
GRANT SELECT ON orders TO repl_user;
CREATE PUBLICATION upgrade_pub FOR TABLE orders;
Every table in the publication needs a replica identity to replicate UPDATE and DELETE. Tables without a primary key fail on the source with “cannot update table … because it does not have a replica identity and publishes updates”. Add a primary key to these tables; if that is not possible, use ALTER TABLE ... REPLICA IDENTITY FULL as a last resort.
2. Copy roles and schema to PostgreSQL 18
Logical replication does not carry table definitions or DDL; you must move them first. Run the PostgreSQL 18 client tools against the 14 server and replace pg14-host with your own server name.
pg_dumpall -h pg14-host -U postgres --globals-only -f globals.sql
psql -U postgres -f globals.sql
pg_dump -h pg14-host -U postgres -d shop --schema-only --no-publications -f shop_schema.sql
psql -U postgres -d shop -v ON_ERROR_STOP=1 -f shop_schema.sql
A “role “postgres” already exists” error while loading the roles is expected. Investigate any other error.
3. Create a subscription on PostgreSQL 18
CREATE SUBSCRIPTION upgrade_sub
CONNECTION 'host=pg14-host port=5432 dbname=shop user=repl_user password=change_me'
PUBLICATION upgrade_pub;
-- 'r' means the initial copy is done and the table is streaming
SELECT srrelid::regclass AS table_name, srsubstate FROM pg_subscription_rel;
The subscription opens a replication slot on the source server. As long as the slot exists, the 14 server keeps the write-ahead log (WAL) for it instead of removing it. Watch the old server’s disk space during the sync.
4. Cut over
Stop application writes on PostgreSQL 14 and confirm that the new server has received every change:
-- On PostgreSQL 14: lag_bytes must be 0
SELECT application_name, state,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes
FROM pg_stat_replication;
Three steps remain on PostgreSQL 18: apply any DDL that changed during the sync, move sequence values forward and drop the subscription. DROP SUBSCRIPTION also removes the slot on the source.
ALTER TABLE orders ADD COLUMN note text; -- DDL that was added on 14 during the sync
SELECT setval('orders_id_seq', (SELECT max(id) FROM orders));
DROP SUBSCRIPTION upgrade_sub;
Tip
Logical replication does not carry sequence values. In our test the sequence on the new server was still at 1 after 1,000 rows had been copied, and the first INSERT failed with a duplicate key error. Add the setval step for every sequence to your cutover script before pointing the application at the new server.
Finally, check on the 14 server that SELECT count(*) FROM pg_replication_slots; returns 0. A forgotten slot keeps accumulating WAL until the old server’s disk fills up.
Method 3: pg_dump and pg_restore
This is the simplest method, and it rebuilds every index on the new server. It is a good choice if you can back up and restore the database within the time set aside for maintenance. The PostgreSQL documentation recommends using the pg_dump and pg_dumpall tools of the new version.
pg_dumpall -h pg14-host -U postgres --globals-only -f globals.sql
pg_dump -h pg14-host -U postgres -d shop -Fc -f shop.dump
createdb -U postgres shop_restored
pg_restore -U postgres -d shop_restored --jobs 2 --no-publications --no-subscriptions shop.dump
The custom format (-Fc) allows a parallel restore with --jobs. Unlike logical replication, a dump also carries sequence values. The restored database has no optimizer statistics, so run ANALYZE afterwards.
Collation, glibc and REINDEX
Indexes on text columns depend on the operating system’s sort rules (glibc collation). If the upgrade also moves you to a newer operating system release, rebuild these indexes before going to production. The best-known example of such a change is glibc 2.28.
Not every method is affected in the same way:
- pg_upgrade carries indexes over as they are, so it is affected.
- Dump/restore and logical replication rebuild indexes on the new server, so they are not affected.
- Columns using an ICU collation are not affected by glibc changes.
PostgreSQL 15 and later record each database’s collation version. On the new server you can compare the recorded and actual versions, verify B-tree indexes with amcheck and rebuild the indexes that need it:
SELECT datname, datcollate, datcollversion,
pg_database_collation_actual_version(oid) AS actual_version
FROM pg_database WHERE datname = 'satis';
-- Structural check of B-tree indexes
CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT c.relname AS index_name, bt_index_check(c.oid, true) AS ok
FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
JOIN pg_am a ON a.oid = c.relam AND a.amname = 'btree'
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public';
-- Indexes that depend on a collatable column
SELECT DISTINCT ic.relname AS index_name
FROM pg_index i
JOIN pg_class ic ON ic.oid = i.indexrelid
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY (i.indkey)
JOIN pg_namespace n ON n.oid = ic.relnamespace
WHERE a.attcollation <> 0 AND n.nspname NOT IN ('pg_catalog', 'information_schema');
-- Rebuild without blocking writes, then record the current collation version
REINDEX INDEX CONCURRENTLY musteri_sehir_idx;
ALTER DATABASE satis REFRESH COLLATION VERSION;
A test result for teams working with Turkish data: in a database created with the tr_TR.UTF-8 locale, lower('IŞIK') and upper('istanbul') returned ışık and İSTANBUL both before and after the upgrade, and the index on the city column stayed in use.
Rollback Plan
Write down the rollback criteria and method before the upgrade. Decisions made under pressure during the work usually make it take longer.
| Method | Way back |
|---|---|
| pg_upgrade –copy or –clone | The old cluster is untouched; simply restart PostgreSQL 14. |
| pg_upgrade –link | If the new cluster never started, rename global/pg_control.old back and start 14. If PostgreSQL 18 has started even once, restore from backup. |
| pg_upgrade –swap | If pg_upgrade reported that the old cluster can no longer be started, restore from backup. |
| Logical replication, dump/restore | The 14 server stays as it is; point the application back at it. Allow for moving data written to 18 after cutover. |
| Cloud service | Know in advance which snapshot you will return to and how long a restore of your data size takes. |
Post-Upgrade Checks
SHOW server_version_num;should return a value starting with 18 (180006for 18.6), and row counts of critical tables should match the source.- Compare
installed_versionanddefault_versioninpg_available_extensionsand update extensions that are behind. - Make sure statistics exist: run the vacuumdb commands above after pg_upgrade, and ANALYZE after dump/restore and on cloud services.
- Review settings whose defaults changed:
password_encryption,io_methodanddata_checksums. - Run the application tests and watch the server logs and slow queries closely during the first business day.
- Take a new full backup on PostgreSQL 18 and test the restore. Physical backups and WAL archives taken on 14 cannot be restored with PostgreSQL 18.
- Clean up temporary resources: old cluster files (after the new backup), replication slots and temporary roles.
When Should You Bring in an Expert?
Upgrading a single small database without extensions is a weekend job. If any of the following applies to you, we recommend working with an experienced team:
- The database is large and the business accepts only a few minutes of downtime.
- You use streaming replicas, a high-availability manager such as Patroni or an existing logical replication setup.
- Extensions such as PostGIS or TimescaleDB, or an application vendor, restrict the target version.
- The upgrade coincides with a new operating system, new hardware or a move to Azure or AWS.
- Nobody on the team has recently rehearsed restoring these databases.
Aryasoft’s senior-only PostgreSQL team plans and runs upgrades end to end: inventory, a rehearsal on a production copy, the cutover itself and the checks that follow. If the upgrade is part of a wider platform change, see our database migration services. If you want regular maintenance once your servers are on 17 or 18, our managed database services, which include a remote DBA service, cover PostgreSQL as well as SQL Server.
Frequently Asked Questions
Sources
The technical details in this guide were checked against the official documentation below in October and November 2026. Dates, versions and cloud policies can change; confirm them on the relevant page before you finalize your plan.
- PostgreSQL: Versioning Policy
- PostgreSQL: Roadmap (minor release schedule)
- PostgreSQL 18 documentation: Upgrading a PostgreSQL Cluster
- PostgreSQL 18 documentation: pg_upgrade
- PostgreSQL 18 release notes
- PostgreSQL 17 release notes
- PostgreSQL 15 release notes
- PostgreSQL 18 documentation: vacuumdb
- PostgreSQL 18 documentation: pg_dump
- PostgreSQL 18 documentation: Logical replication restrictions
- PostgreSQL 18 documentation: Logical replication configuration settings
- PostgreSQL 18 documentation: CREATE SUBSCRIPTION
- PostgreSQL 18 documentation: Collation Support
- PostgreSQL Wiki: Locale data changes
- Microsoft Learn: Major version upgrades in Azure Database for PostgreSQL
- Microsoft Learn: Azure Database for PostgreSQL extended support
- Microsoft Learn: Azure Database for PostgreSQL version policy
- AWS: Amazon RDS for PostgreSQL release calendars
- AWS: Choosing a major version for an RDS for PostgreSQL upgrade
- AWS: Amazon RDS Extended Support
- AWS: Amazon RDS Extended Support charges
PostgreSQL Upgrade
Leave PostgreSQL 14 before support ends
Talk to Aryasoft’s senior PostgreSQL team. We assess your servers, rehearse the upgrade on a production copy and run the cutover with a written rollback plan.