All Articles
CategoryBackend
Reading Time
16 min read
Published
2026-10-14
Word Count
3,790words

Grab a coffee — this one is a deep dive!

PostgreSQL 19 Is Coming: What's New and the Upgrade Plan

Summary

PostgreSQL 19 is still in beta: Beta 3 status, features pulled back in September 2026, the 18.6 security patches, and a zero-downtime upgrade plan with pg_upgrade.

  • PostgreSQL 19 is still in beta as of September 23, 2026 (latest: Beta 3, August 13, 2026); no official GA date has been set.
  • Major features like SQL/PGQ (property graph queries) and FOR PORTION OF were pulled back mid-beta in September 2026 and won't be in PostgreSQL 19.
  • On August 13, 2026, a joint patch set closed 28 security vulnerabilities across 18.6/17.11/16.15/15.19/14.24; PostgreSQL 14 reaches EOL on November 12, 2026.
  • Before pg_upgrade: standard_conforming_strings is always on, RADIUS auth is removed, max_locks_per_transaction's default is now 128, and you must pull your extension inventory.
PostgreSQL 19 Is Coming: What's New and the Upgrade Plan

PostgreSQL 19 is still moving through beta as of Beta 3, released on August 13, 2026 — the same announcement also shipped security patches for 18.6, 17.11, 16.15, 15.19, and 14.24. This piece covers where PostgreSQL 19 actually stands as of September 23, 2026, which features got pulled back mid-beta, and the concrete plan for moving a production 18.x install to 19.

💡 Pro Tip: With PostgreSQL 19 still not GA, get the 18.6 security patch into production first — don't leave an open door while you wait on the 19 upgrade plan.

Table of Contents

PG 19 timeline and beta status

The PostgreSQL Global Development Group released the third beta of PostgreSQL 19 on August 13, 2026, described as "the third beta release of PostgreSQL 19" — the same package fixes 28 security vulnerabilities and over 110 bugs.

The official roadmap page describes PostgreSQL 19 as "planned for September 2026," but doesn't give a firm RC1 or GA date. As of September 23, 2026, the "Important Dates" table on the PostgreSQL 19 Open Items page lists Beta 4 as September 24, 2026; in the same table, the RC 1 and GA rows are still "TBD." The commit freeze planned for September 19 and the "GA by end of October" target come from a community source (a contributor blog post on thebuild.com) — that's not an official commitment.

The same day also patched five stable releases: the PostgreSQL 19 Beta 3 announcement shipped security patches for all five supported major versions (18, 17, 16, 15, 14) too — even preparing a beta release, the project didn't let up on stable-branch security maintenance. The "18.6 patch set" section below covers this package in detail.

As of this article's publish date of October 14, 2026, there is no guarantee PostgreSQL 19 has reached GA. Every section below describes current behavior during the beta process; confirm the version's actual status on postgresql.org before moving to production.

Highlighted changes and what's actually accelerating things

Features that stuck around

  • REPACK / REPACK (CONCURRENTLY): a new command that merges what VACUUM FULL and CLUSTER used to do separately. CONCURRENTLY isn't a standalone keyword — it's an option inside the parenthesized option list (REPACK [ ( option [, ...] ) ] ...). Run without options, it takes an ACCESS EXCLUSIVE lock on the table, blocking every other operation on it — so in production, prefer the (CONCURRENTLY) variant.
  • ON CONFLICT DO SELECT ... RETURNING: after an upsert, you can now get the conflicting row back via RETURNING too.
  • IGNORE NULLS in window functions: makes it easier for functions like LAG/LEAD to skip NULLs and find the actual previous/next value.
  • Sequence support in logical replication: logical replication now replicates sequence values too; the release notes say this is enabled through CREATE SUBSCRIPTION, ALTER SUBSCRIPTION ... REFRESH PUBLICATION, and ALTER SUBSCRIPTION ... REFRESH SEQUENCES.
  • Parallel index vacuum + scoring in autovacuum: autovacuum can now vacuum a table's indexes with parallel worker processes; a new scoring system decides which table gets vacuumed first.
  • WAIT FOR: a new command that waits for a standby to replay up to a specific LSN — usable for a "read-your-writes" pattern.
  • default_toast_compression is now lz4: the default algorithm for large field compression has changed.

Reverted features (the September 2026 revert wave)

Since Beta 3 (August 13), several major features judged too immature for GA have been pulled back from PostgreSQL 19's stable development branch:

  • SQL/PGQ (property graph queries — the CREATE PROPERTY GRAPH command and related graph-query syntax) — 47 commits reverted on September 7. The rationale was post-release bug risk; which version it returns in is unclear, since it was pulled from the development branch too, not just the 19 branch.
  • FOR PORTION OF (temporal UPDATE/DELETE) — reverted September 15, from both the 19 branch and the development branch.
  • pg_get_role_ddl(), pg_get_tablespace_ddl(), pg_get_database_ddl() — reverted from the 19 branch only on September 12; still alive in the development branch targeting PostgreSQL 20.
  • Online data checksum enable/disable — reverted from the 19 branch on September 16; survives only on master (targeting PostgreSQL 20).
  • MERGE PARTITIONS had already been deferred to a later release before this.

So if you run into a source claiming "PostgreSQL 19 has graph queries," that source is likely frozen at a Beta 1/2 snapshot — as of September 23, 2026, this feature is not in PostgreSQL 19. The official release notes page doesn't reflect these reverts yet either; the top of the page reads "Release date: 2026-??-??, AS OF 2026-07-18" — the list is a July 18, 2026 snapshot.

In practice, here's how REPACK (CONCURRENTLY) works for online maintenance — note that the option is given in parentheses:

sql
1-- CONCURRENTLY is a parenthesized option: REPACK [ ( option [, ...] ) ] table
2-- The table stays accessible throughout the rewrite; the ACCESS EXCLUSIVE
3-- lock is only taken briefly, to swap the table and index files.
4REPACK (CONCURRENTLY) orders;
5 
6-- If locking is acceptable (during a maintenance window), it's faster:
7REPACK orders;

The 18.6 patch set and the vulnerabilities it closes — patch first

The August 13, 2026 announcement didn't just ship 19 Beta 3 — it also brought security patches for every supported major version: 18.6, 17.11, 16.15, 15.19, and 14.24. In total, 28 security vulnerabilities and over 110 bugs were fixed. Notable CVEs:

  • CVE-2026-6471 — a missing privilege check in logical decoding let a non-superuser role with REPLICATION privilege dlopen any file visible to the OS account running the server, via a logical decoding plugin of their choice (CVSS 7.2).
  • CVE-2026-14663 — pgcrypto silently encrypted to and decrypted from plaintext on ciphers disabled by OpenSSL, with which ciphers are disabled depending on the OpenSSL version and configuration. Per the official CVE wording, a user can recover the plaintext "via direct observation of the faulty ciphertext" — worse, if the application accepts encrypted data as input, decryption succeeds even with the wrong key, erasing the modest protection the Modification Detection Code (MDC) was supposed to provide.
  • CVE-2026-6464 — in psql, when COPY FROM STDIN failed early, subsequent data lines could be processed as psql commands (CVSS 8.1).

If you're still running PostgreSQL 18.x, 17.x, 16.x, 15.x, or 14.x, you need to apply this patch set before waiting for PostgreSQL 19 — these aren't 19's novelties, they're open doors in your current production.

The same announcement also carries a date warning: PostgreSQL 14 stops receiving patches on November 12, 2026. If you're still on PostgreSQL 14, prioritize your migration plan to 19 around this date.

Application-layer impact (Prisma/Drizzle driver compatibility)

PostgreSQL 19's release notes list no breaking change to the wire protocol, so low-level drivers like pg, postgres.js, and Drizzle can usually talk to a new major version without an extra update. But don't confuse that with "official support."

On the Prisma side, here's the catch: Prisma's "supported databases" page doesn't give a version-by-version compatibility list for PostgreSQL. It lists PostgreSQL (including Prisma Postgres) as "Release candidate" via the @prisma/orm-postgres package, connecting through a standard connection string. So you can't read a version number off this page to answer "is PostgreSQL 19 supported?" — check the page's current state yourself.

Practical advice: while PostgreSQL 19 is still in beta, don't tie your production ORM to it. If you're going to try it in staging, first check Prisma/Drizzle's current "supported databases" page; if there's no breaking change in the wire protocol, you shouldn't expect a driver-level issue, but don't present that as "guaranteed supported."

In short: in Prisma ORM 7 and earlier, the datasource block and provider = "postgresql" line in schema.prisma don't change; in Prisma ORM 8, the schema file's name became the contract — per the docs, "it has no datasource or generator blocks because the connection string lives in prisma.config.ts." Either way, moving to PostgreSQL 19 only changes which server that connection string points at.

Downtime planning and rollback with pg_upgrade

The standard path to PostgreSQL 19 is still pg_upgrade; dump/restore via pg_dumpall or logical replication are alternatives. But there are breaking changes you need to know first:

  • standard_conforming_strings is now always on. If your pre-19 pg_dump output was taken with standard_conforming_strings = off, those dumps may not load cleanly into 19. Don't restore old dumps without reviewing them.
  • CR/LF (line-ending characters) are now forbidden in database, role, and tablespace names. pg_upgrade outright refuses to upgrade clusters carrying such names; the reason for the change is security.
  • RADIUS authentication has been removed entirely — the implementation, which only worked over UDP, was found "irrecoverably insecure" and ripped out. If you use RADIUS in pg_hba.conf, you need to switch to another auth method before upgrading.
  • JIT is now off by default. The release notes state the reason plainly: the cost model wasn't trusted ("this costing has been determined to be unreliable"). Installations running large analytical queries need to turn JIT on manually (jit = on).
  • MD5 password authentication now logs a warning on every successful login (controlled via md5_password_warnings). MD5 was deprecated in PostgreSQL 18 — good reason to move to scram-sha-256.
  • max_locks_per_transaction's default went from 64 to 128 — but that's not extra headroom. The release notes say it plainly: "Lock size allocation has changed, so effectively settings must now be doubled to match their capacity in previous releases." So if you set this value manually on PG ≤18, you need to double it to keep the same capacity (256 becomes 512).

The downtime plan should follow these steps:

bash
1# 1) Dry run — check compatibility without touching real data
2pg_upgrade \
3 --old-datadir=/var/lib/postgresql/18/main \
4 --new-datadir=/var/lib/postgresql/19/main \
5 --old-bindir=/usr/lib/postgresql/18/bin \
6 --new-bindir=/usr/lib/postgresql/19/bin \
7 --check
8 
9# 2) The real upgrade (--link saves disk space and time,
10# but KEEP the old data directory as your rollback guarantee)
11pg_upgrade \
12 --old-datadir=/var/lib/postgresql/18/main \
13 --new-datadir=/var/lib/postgresql/19/main \
14 --old-bindir=/usr/lib/postgresql/18/bin \
15 --new-bindir=/usr/lib/postgresql/19/bin \
16 --link
17 
18# 3) If pg_upgrade finds anything needing post-upgrade work, it warns
19# and generates .sql scripts; it names them in its own output. The
20# documentation states exactly how to run these scripts:
21# "Each script should be run using: psql --username=postgres --file=script.sql postgres"
22psql --username=postgres --file=update_extensions.sql postgres

The rollback plan is simple but requires discipline: don't delete the old data directory the moment the upgrade finishes in --link mode; keep it until at least one full verification cycle (smoke tests + critical queries) has passed. If something goes wrong, restarting the old cluster is a much faster recovery path than deleting the new one.

Pulling the extension inventory (the thing that actually blocks the upgrade)

In practice, most pg_upgrade surprises come from extensions, not version numbers. PostgreSQL's own pg_upgrade documentation states this outright: if extension updates are available, pg_upgrade reports it and generates a script you can run afterward. Treating the upgrade as "done" without seeing and running this script leaves a silent mismatch in production between the pg_extension version and the actual schema — the usual symptom is "function not found" or unexpected behavior.

Before starting the upgrade, pull this inventory:

sql
1-- Name, version, and schema of every installed extension
2SELECT extname, extversion, extnamespace::regnamespace AS schema
3FROM pg_extension
4ORDER BY extname;

If you use btree_gist, there's a separate warning. What changed isn't the opclass definition — it's the default marking: the release notes summarize it as "Change the default index opclasses for inet and cidr data types from btree_gist to GiST," stating the reason plainly — "The btree_gist inet/cidr opclasses are broken because they can exclude rows that should be returned." REINDEX can't fix this, since it just rebuilds the same flawed opclass; per the documentation, the problem is "unfixable without redefining the contents of indexes that use these opclasses." So the fix is to replace, not rebuild: recreate the index with the built-in inet_ops opclass and drop the old one — CREATE INDEX good_index ON mytable USING GIST (addr inet_ops); then DROP INDEX bad_index;. Skip this and pg_upgrade refuses to upgrade, telling you to change the indexes first.

Checklist for every extension:

  • Has the shared library (.so) file been recompiled for the new major version?
  • Does the extension's own CHANGELOG explicitly state PostgreSQL 19 compatibility?
  • Does pg_upgrade --check output a warning for this extension?

Versions patched on August 13, 2026, and what they signal:

Version
Patch date
Note
19 Beta 3
2026-08-13
Still beta, not for production
18.6
2026-08-13
Current stable, viable upgrade target
17.11
2026-08-13
Supported
16.15
2026-08-13
Supported
15.19
2026-08-13
Supported
14.24
2026-08-13
EOL on November 12, 2026

When to wait, when to move

As of September 23, 2026, PostgreSQL 19 is still in beta; the RC1 and GA dates are officially "TBD." PostgreSQL's recent annual cadence (PostgreSQL 18 shipped September 25, 2025) makes a September–October GA plausible, but that's a signal, not a guarantee.

Scenario
Recommendation
Production, critical data
Wait for GA, target at least one point release (19.1) after it
Staging/test environment
You can start trying Beta 3 now, but don't wire upgrade scripts to prod
New project, no data yet
Develop on beta, migrate with pg_dumpall once GA ships
Extension-heavy installation (especially btree_gist)
Pull your extension inventory now, test on a test cluster before GA
Running PostgreSQL 14
Patch to 14.24 now without waiting for 19; put the November 12, 2026 EOL on your calendar

PostgreSQL's support policy retires every major version 5 years after release — PostgreSQL 18 shipped September 25, 2025, and will be EOL November 14, 2030. PostgreSQL 19's exact EOL can't be calculated yet, but the same 5-year window applies.

No upgrade without a backup + restore rehearsal

PostgreSQL's own release notes make this an explicit requirement: "A dump/restore using pg_dumpall or use of pg_upgrade or logical replication is required for those wishing to migrate data" — meaning anyone migrating data must use one of pg_dumpall dump/restore, pg_upgrade, or logical replication; there is no "none of the above" option.

In practice, this means: even if pg_upgrade --check comes back clean, you don't try the upgrade directly in production. In order:

  1. Take a current dump or physical copy of production.
  2. Restore that copy onto a separate staging cluster.
  3. Run pg_upgrade --check on staging, then the real upgrade.
  4. Test your application's critical queries on staging (especially tables using extensions and btree_gist indexes).
  5. Only after these steps pass cleanly, apply the same plan to production — and keep the old data directory until verification is complete.

An upgrade that skips the restore rehearsal wasn't "attempted" — it was "left to chance."

GOLDEN TIP

The most valuable insight in this article

This tip holds the article's most important takeaway.

Easter Egg

You found a hidden gem!

There's a hidden detail in this section. Want to uncover it?

Reader Reward

A one-page pre-upgrade checklist rolling up every step in this article — check them off in order before moving to production.

FAQ

What's new in PostgreSQL 19?

Notable lasting changes as of September 23, 2026: the built-in REPACK / REPACK (CONCURRENTLY) command for online table maintenance, ON CONFLICT DO SELECT ... RETURNING, IGNORE NULLS in window functions, sequence support in logical replication, and parallel index vacuum + scoring in autovacuum. SQL/PGQ (property graph queries) and FOR PORTION OF (temporal UPDATE/DELETE), both tried during beta, were reverted in September 2026 and won't be in PostgreSQL 19.

How do you upgrade from PostgreSQL 18 to 19?

The standard path is pg_upgrade (or dump/restore with pg_dumpall, or logical replication). First do a dry run with pg_upgrade --check, then run the real upgrade with --link. Before upgrading, check that standard_conforming_strings will always be on, that RADIUS auth has been removed, that max_locks_per_transaction's default rose to 128, and that every extension may need recompiling.

When will PostgreSQL 19 reach GA?

As of September 23, 2026, no firm GA date has been announced. The "Important Dates" table on the PostgreSQL 19 Open Items page lists Beta 4 as September 24, 2026, but the RC 1 and GA rows in the same table are still "TBD"; "GA by end of October" is only a target discussed in community sources. The historical cadence (PostgreSQL 18 shipped in September 2025) is a signal, not a guarantee.

Does Prisma support PostgreSQL 19?

Prisma's "supported databases" page doesn't list PostgreSQL version-by-version: it shows PostgreSQL (including Prisma Postgres) as "Release candidate" via the @prisma/orm-postgres package, connecting through a standard connection string. So you can't get a clean "19 supported" answer there — check its current state yourself before production. With no breaking change in the wire protocol, a driver-level issue is unlikely, but that's not a guarantee.

What changes if I use btree_gist?

PostgreSQL 19 moves the default opclass for inet and cidr from btree_gist to the built-in GiST, because btree_gist's inet/cidr opclasses are broken — they can exclude rows that should be returned. pg_upgrade refuses to upgrade a cluster carrying these indexes and tells you to change them first. REINDEX doesn't help (it just rebuilds the same flawed opclass); the correct path is recreating the index with inet_ops and dropping the old one: CREATE INDEX good_index ON mytable USING GIST (addr inet_ops); then DROP INDEX bad_index;.

What should I do if I use RADIUS authentication?

RADIUS authentication has been completely removed in PostgreSQL 19 because the implementation, which only worked over UDP, was found insecure. If you have RADIUS in your pg_hba.conf, you need to switch to another authentication method (SCRAM, for example) before upgrading.

Conclusion

As of September 23, 2026, PostgreSQL 19 is still in beta with no firm GA date — even major features tried during Beta 3, like SQL/PGQ and FOR PORTION OF, got pulled back. That's the real reason behind the "wait for GA" advice: the release is still taking shape.

Two things to do right now, independent of each other: first, while waiting on 19, tighten the contract above your database layer with REST API design principles; second, keep your current PostgreSQL version (18.6/17.11/16.15/15.19/14.24) patched. On a PostgreSQL-based platform like Supabase, the major-version transition is usually the provider's job — see Supabase Edge Functions and the Deno runtime. Running an edge-native setup with Drizzle? The Drizzle ORM + Turso/SQLite edge pattern piece shows what changes at the driver level. On Cloud SQL, review the Firebase Data Connect + GraphQL + Cloud SQL integration. For vector workloads, before choosing pgvector over a dedicated vector database, the Pinecone/Weaviate/Qdrant comparison is a useful reference.

In short: put PostgreSQL 19 on your production roadmap now, but don't treat any date as a commitment until it says "GA."

Sources

Tags

#PostgreSQL#pg_upgrade#database#backend#Prisma#security patch#REPACK
Muhittin Çamdalı

Muhittin Çamdalı

Senior Mobile Engineer

Senior Mobile Engineer with 12+ years of experience. Expert in iOS, Android and cross-platform architectures with Swift, SwiftUI, Kotlin and Flutter. I build performant, user-friendly mobile apps.

iOS Development News

Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.

Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy

Share