Skip to content

When Will Postgres 19 Be Released?

Updated 21 min readPostgreSQLDatabases

Short version: PostgreSQL 19 has a date at last, and it is not in October. The project released RC 1 on October 15, 2026, and that announcement names November 19, 2026 as the planned date for general availability, with a second release candidate, RC 2, on November 12. This is the first time a specific GA date has appeared in an official release announcement for this cycle. It is three weeks later than the end-of-October goal the Release Management Team was working to in September: the move was made on October 10, when Jonathan Katz told pgsql-hackers the team was pushing GA to November 19, one week after the scheduled minor release, and adding RC 2 so the pile of fixes in the back branches ships in a candidate first. The source tree matches the announcement: REL_19_RC1 is stamped on the branch as of October 12, and the release notes still carry the literal placeholder 2026-??-?? where the release date goes, which is normal, because that line gets filled in at GA. If you want to test 19 today, RC 1 is the newest build upstream. Layerbase is still on 19.0.0-beta.3, and RC 1 is the build we plan to add.

Last checked 2026-10-15. November 19 is a plan rather than a promise, so I will revise this post if it moves again.

The reason people are asking is that 19 has slipped, twice. PostgreSQL has shipped a major version every September or October for a decade, this one spent the summer reverting features, and the GA target has now moved out of that window entirely. What follows is the dated timeline, why the slip happened, what is still in the release, what has been pulled out, and how to actually get your hands on 19 before it ships.

What has actually been announced

Here is every milestone with a date attached, from the release announcements, the hackers list and the PostgreSQL 19 Open Items page. Nothing below is my estimate: the two future rows are dates the project has published, and it can still move them.

MilestoneDateStatusWhat it means
Feature freezeApril 8, 2026 12:00 UTCHappenedEnd of the last CommitFest. Nothing new gets into 19 after this; only fixes and reverts.
Beta 1June 4, 2026HappenedFirst public build of the 19 branch. Feature set is nominally frozen, catalog format is not.
Beta 2July 16, 2026HappenedSecond beta, rolling up fixes from beta 1 testing.
Beta 3August 13, 2026HappenedShipped alongside the 18.6 / 17.11 / 16.15 minor releases. Superseded upstream by Beta 4, and still the build Layerbase offers.
Beta 4September 24, 2026HappenedFourth beta, one more than this project usually needs. Stamped in the tree as 19beta4 on September 21, three days ahead of release, same gap as betas 1 through 3. Superseded upstream by RC 1. Layerbase skipped it.
RC 1October 15, 2026HappenedFirst release candidate, and the first build this cycle that is meant to be close to what ships. Stamped in the tree as 19rc1 on October 12, three days ahead of release, the same gap every beta had. Not in the Layerbase picker yet; it is the build we plan to add.
RC 2November 12, 2026AnnouncedAdded on October 10, after RC 1 was already scheduled, so the fixes accumulating in the back branches ship in a candidate before GA. It lands the same day as the scheduled minor release.
GA (19.0)November 19, 2026Announced, plannedThe date in the RC 1 announcement, one week after the November 12 update release. Conditional by its own wording: a problem found in RC 2 can still push it or add another candidate. The release notes in the tree read 2026-??-?? until it happens.

November 19 is the third date this cycle has carried, so the trail is worth walking. It starts with Jonathan Katz's September 3 message to pgsql-hackers, which is worth quoting directly because the wording matters:

You may notice that we're doing a Beta 4 a bit later than normal this year. This is primarily due to handling the influx of issues that have been reported that have taken additional time to handle. The current goal is to try to get PostgreSQL 19 to GA by the end of October so we can try to stay on our usual schedule of being within the Sept/Oct timeframe for GA.

"The current goal is to try" was doing a lot of work in that sentence, and it was written that way on purpose. On September 28 the team put real dates behind the goal: RC 1 on October 15 and GA on October 29, with no second candidate. RC 1 held, to the day. GA did not. The October 10 update moved it to November 19 and inserted RC 2 on November 12, and that is the schedule the RC 1 announcement carries.

So the end-of-October goal missed by three weeks, and what actually stretched is the gap between the first candidate and the release: two weeks as planned in September, five weeks as scheduled now. That is the shape of a team that has decided it would rather be late than ship the thing twice.

How late is this, historically

Every first-release date below is from the project's own versioning policy page.

VersionGA date
13September 24, 2020
14September 30, 2021
15October 13, 2022
16September 14, 2023
17September 26, 2024
18September 25, 2025

Four of the last six landed in the back half of September. The outlier is 15, which arrived on October 13 after its own schedule trouble. A November 19 release does not just set a new late record for this stretch, it leaves the September/October band the project has kept for a decade. The team spent most of the cycle trying to stay inside that window, said so in public, and in the end took the later date over the shakier one.

Notice also that there were only three betas for most of those cycles. A fourth beta at all is a signal, and 19 got one; a second release candidate is rarer still, and 19 is getting that too.

Why it is late

The short answer is that a lot of things committed just before the April freeze turned out not to be ready, and finding that out took the whole beta period.

Postgres runs on a one-way cliff: a feature either lands before the freeze or waits a year. That creates enormous pressure to commit in the last days of the last CommitFest, which is exactly when a patch has the least review behind it. Several of 19's headline features went in that way, and post-commit review over the summer found design-level problems rather than ordinary bugs. A bug you fix. A design problem you either fix properly, which takes a release cycle, or you revert.

The project chose to revert, repeatedly, and it kept choosing that through mid-September. Christophe Pettus wrote a good post-mortem of the pattern on September 14, and Snowflake published a tally of the reverts that counts 53 revert commits across the cycle. I have not independently reproduced that count, so treat the number as their tally; the individual reverts below I did verify against the commit log.

The wave has broken. The last feature revert on the 19 branch was online data checksums on September 16, and a month later, through Beta 4 and the RC 1 stamp, that still holds: no feature revert has landed on REL_19_STABLE since. The one piece of late cleanup worth naming is paperwork rather than code. On October 12 the release team removed a release-notes entry for letting logical decoding plugins declare that they do not read shared catalogs, because the commit behind it had already been reverted and the note had outlived it. Everything else on the branch since mid-September is bug fixes, documentation and translation updates, which is exactly what the run-up to a release is supposed to look like.

The important thing to take from it is what the reverts mean. A release that pulls a feature in September is a release doing its job. The alternative was shipping SQL/PGQ with a design nobody was happy with and living with it for five years of support.

What is still in PostgreSQL 19

One caution before the list, though a smaller one than last month. The 19 release notes carry an "AS OF" stamp, and at the REL_19_RC1 tag that stamp reads 2026-10-09, up from 2026-09-14 in September and 2026-07-18 when I first wrote this. It is now past every revert in the cycle, so the notes are current in a way they were not before. The major-features list at the top was rewritten on September 23 by the release team and still stands. Every item below I checked against the release notes at the RC 1 tag and the commit log, not against a summary.

SQL and developer features

  • INSERT ... ON CONFLICT DO SELECT ... RETURNING. Get-or-create in one statement, with the conflicting row returned instead of an error, and optionally locked with FOR UPDATE or FOR SHARE. Still documented in the INSERT reference.
  • IGNORE NULLS and RESPECT NULLS on window functions, covering lead(), lag(), first_value(), last_value() and nth_value().
  • COPY TO can emit JSON, including a single array via the FORCE_ARRAY option.

Performance

  • Faster foreign key checks, via the batched RI fast path. This one is worth stating plainly because a secondary write-up I read suggested it had been pulled: it has not. The commit log for September shows fixes to it (snapshot ordering, collation mismatch fallback), not a revert, and it kept taking fixes right up to Beta 4 (permission checks, operator family invalidation). It is in, and "quicker foreign-key checks" is still in the release notes' own summary of the release.
  • io_method = worker now scales its worker pool automatically between io_min_workers and io_max_workers instead of running a fixed count, with io_worker_idle_timeout and io_worker_launch_interval controlling the ramp.
  • pg_plan_advice and its companion pg_stash_advice, a supported way to stabilize planner decisions for a query rather than fighting the planner with enable_* flags.

Maintenance and vacuum

  • REPACK, in core, doing what VACUUM FULL and CLUSTER did plus a CONCURRENTLY mode that keeps reads and writes flowing until the final swap. It leads the release team's own major-features list, and it absorbed fixes right up to the candidate: dropped-column values are now cleared during a concurrent repack (October 3, October 7) and its documentation page was rewritten on October 7. A feature taking that many fixes in the last fortnight is worth testing rather than assuming.
  • Parallel autovacuum, capped by autovacuum_max_parallel_workers, along with a scoring system that prioritizes the tables that most need attention instead of taking them in discovery order. The release team lists this pair as one of the headline features of 19.

Replication and monitoring

  • WAIT, a new command that blocks until a standby has replayed up to a chosen LSN, which is what you want for read-your-writes against a replica. Note the name: it was committed as WAIT FOR and renamed to WAIT in the documentation on September 14, so older write-ups will call it the wrong thing.
  • CREATE PUBLICATION and ALTER PUBLICATION accept an EXCEPT TABLE clause, so FOR ALL TABLES can carve out exceptions instead of being all or nothing. Note the final spelling: the clause was renamed about a week before the feature freeze, so older write-ups show it without the TABLE.
  • Logical replication of sequence values. Sequences were the long-standing hole in logical replication, and a failover that left yours behind made for a genuinely bad afternoon.
  • Logical replication can be turned on without restarting the server, provided wal_level is already replica. This and the sequence work both sit on the release team's own major-features list, so they are not going quietly.

Defaults that changed

These two are the ones to actually test against, because they change behavior on an existing schema without you asking.

  • jit now defaults to off. The docs are blunt about why: the cost model that decided when to JIT "has been determined to be unreliable." If you benchmarked a query on 18 with JIT firing, it will not fire on 19 until you turn it back on.
  • default_toast_compression now defaults to lz4, with a caveat: the current docs say "the default is lz4 (if available); otherwise, pglz", and availability means the build was compiled with lz4 support. Check the value on your actual server rather than assuming, especially if you build Postgres yourself.

What is now expected to be out

Each of these was committed for 19 and has since been reverted. All of them are verifiable in the commit log, and none of them will be in 19.0.

Online enabling and disabling of data checksums. Turning checksums on or off on a running cluster, no re-initdb and no dump and restore. I had this in the "still in" list when I first published this post. That was wrong: it was reverted on September 16, the day before, unwinding thirty commits. The commit message is unusually direct about why, and the reasoning is worth reading if you want to understand this whole release cycle:

The feature to enable, or disable, data checksums in an online cluster saw a number of postcommit fixes during the beta period. Suspicions were raised about the risk of more issues surfacing after GA. To avoid shipping code which may have bugs, this reverts in full, or in part, the following commits

Two small pieces were kept on their own merit: a fix for offline checksums not preserving initial state in pg_control_init, and an extra line in page-verification logging that says whether the buffer will be zeroed. The feature itself is gone, and the release notes no longer mention it. If you were waiting on 19 to turn checksums on without rebuilding the cluster, you are waiting on 20.

pg_get_role_ddl(), pg_get_tablespace_ddl() and pg_get_database_ddl(). Server-side functions that emit the CREATE statement for a role, a tablespace or a database, which would have made cluster-level objects scriptable without shelling out to pg_dumpall. Reverted September 12, taking the twelve follow-up commits it had already accumulated with it.

SQL/PGQ property graph queries. The SQL standard's graph query syntax, letting you declare a property graph over existing tables and pattern-match across it with GRAPH_TABLE. This was the single biggest feature in the release and the revert was correspondingly large, 124 files and around 16,000 lines removed on September 7. The reasons were readiness and design rather than any one bug. The work is not abandoned, but a feature of that size restarting after a revert is not a safe bet for 20 either.

ALTER TABLE ... MERGE/SPLIT PARTITION(S). Declarative partition reshaping without hand-rolling a detach, create, move, attach dance. Reverted August 26 with the commit message citing "multiple design issues which are too late to address in this release cycle." That phrasing suggests a return once the design settles, but it has now missed two cycles.

UPDATE/DELETE ... FOR PORTION OF. The temporal DML half of the SQL:2011 period support, where updating a row for part of its validity period automatically splits it and keeps the leftovers. Reverted September 15, and the revert had to unwind 23 commits, which tells you how much fixing it had already absorbed. PostgreSQL 18's WITHOUT OVERLAPS temporal constraints are unaffected and still there.

GROUP BY ALL. Shorthand for grouping by every non-aggregated select-list column, the thing DuckDB and Snowflake users keep asking for. Reverted July 17 after post-commit review found it missed the special handling for entries that also appear in ORDER BY, producing wrong results with non-default equality semantics. The commit message says outright: "We'll revert and try again in v20." Of everything on this list, this is the most likely to come back.

Non-text output formats for pg_dumpall. Directory and custom format dumps of a whole cluster, which would have made pg_dumpall parallel-restorable like pg_dump already is. Reverted June 18, early enough that most beta write-ups never mentioned it.

Provider-specific identifier casefolding. A pair of changes meant to stop identifier case handling depending on the process-wide libc locale. Reverted September 11 along with the related change that forced LC_COLLATE to C in the postmaster, after an unintended behavior difference turned up for the builtin provider. Invisible to almost everyone, but if you were counting on 19 to fix locale-dependent identifier folding, it does not.

CREATE SCHEMA subcommand expansion. Support for more object types inside a CREATE SCHEMA block, plus the reordering work that went with it, both reverted September 11. Unrelated CREATE SCHEMA work did survive: forward references in FOREIGN KEY clauses inside a CREATE SCHEMA block are in 19.

Letting logical decoding plugins declare they do not read shared catalogs. The smallest item here and the last to be tidied up. This is the one entry where I am linking the cleanup rather than the revert: the release team deleted the release-note line on October 12, three days before RC 1, and that commit message is what states the underlying commit had been reverted. I could not find the revert itself in the branch log, so take the fact from upstream rather than from me. Either way the feature is not in 19, and if you read the 19 notes before October 12, that line was stale.

One loose end from the first version of this post, now closed. A widely repeated claim held that the switch of default_toast_compression to lz4 had been reverted. There is a revert in the log, and it is not the one people meant. The first attempt landed on March 4, was reverted the next day, and was re-landed the same day as "take two". The second version is the one in the tree, and the configuration docs on the branch still read "The default is lz4 (if available); otherwise, pglz." So lz4 is in, and the rumor is a half-memory of a revert that lasted about a day in March.

There is one wrinkle worth knowing, because it trips people up when they go looking. postgresql.conf.sample ships with #default_toast_compression = pglz, which looks like a contradiction. It is not: the sample file cannot be conditional on build options, so initdb rewrites that value in place when the build has lz4 support. Read the setting off a running server, not out of the sample file.

How to run PostgreSQL 19 today

You do not have to wait for GA to find out whether your app survives 19. That is the entire point of a pre-release, and bug reports filed now are worth ten filed after it ships.

I run Layerbase, which hosts PostgreSQL among other engines, so treat this section as the vendor part of the post. Everything above stands on its own.

Layerbase Cloud. Open the create flow, pick 19.0.0-beta.3 from the version picker (it carries a Beta chip so you cannot grab it by accident), and you have a hosted 19 instance with TLS and the web query console about thirty seconds later. It is otherwise a completely normal database: backups, hibernation on idle, and the free tier applies, so trying it costs nothing and does not need a card.

Upstream has moved twice since we added that build, Beta 4 on September 24 and RC 1 on October 15, and our picker is still on 19.0.0-beta.3, so beta 3 is what you get from us today. Skipping Beta 4 was deliberate: a candidate was weeks out, every beta is a dump and restore away from the next build, and making you migrate twice to land in the same place is not a favor. RC 1 is the build we plan to add. For what a beta is actually for, running your migrations and your test suite against a 19 instance, beta 3 will tell you most of what RC 1 would. Two differences are worth naming. Online data checksums still exist on beta 3 and will not be in 19.0, so do not build on them. And the REPACK and planner fixes that landed through early October are not in beta 3, so if REPACK (CONCURRENTLY) is the feature you are evaluating, test it again once you are on a candidate.

Locally. Layerbase Desktop runs the same build: create a database, pick the beta from the version list. From a terminal, the Layerbase CLI does it headless with no account needed:

bash
npm i -g layerbase
lbase create pg19 -e postgresql --db-version 19.0.0-beta.3 --start --connect

One platform note for local runs: the 19 beta builds are macOS and Linux only right now. Stable PostgreSQL 15 through 18 runs natively on Windows, but the beta needs WSL. Expect native Windows builds once 19.0 proper lands.

Two things that will bite you if you skip them. Pre-release data directories are not guaranteed to carry forward: not from one beta to the next, not from a beta to a release candidate, and not into 19.0 on November 19. Moving a beta.1 database to beta.3, or a beta.3 database to the release, is a dump and restore, never an in-place upgrade. Plan for it now and it is a pg_dump away; plan for it the week of the release and it is a bad afternoon. Second, the default version for new Layerbase databases is still 18, and it stays 18 until 19.0 actually ships. Nothing about your existing databases changes because a pre-release build exists.

Here is a snippet that confirms you are actually on 19 and exercises two features I verified are still in, so it will keep working through GA:

sql
SELECT version();

SHOW jit;                        -- expect: off  (this is new in 19)
SHOW default_toast_compression;  -- expect: lz4  (pglz if built without lz4)

CREATE TABLE tags (
  id   bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  name text NOT NULL UNIQUE
);

-- ON CONFLICT DO SELECT: run this twice, get the same id both times,
-- with no dead tuple and no second round trip
INSERT INTO tags (name) VALUES ('postgres')
ON CONFLICT (name) DO SELECT
RETURNING id, name;

If the second INSERT returns the existing row instead of raising a syntax error, you are on 19. On 18 and earlier the parser rejects DO SELECT outright.

For more on what is in the beta and how it behaves, see Postgres 19 Beta is live on Layerbase. For the version you are probably actually running, What's New in PostgreSQL 18 covers uuidv7(), virtual generated columns, and skip scan.

What to do between now and GA

Three things, in order of how much they will save you.

Run your test suite against the beta in CI. Not a manual poke at a psql prompt, an actual run of your migrations and your tests against a 19 instance. This is the whole value of the beta period and almost nobody does it. A throwaway beta database per CI run costs nothing and catches the incompatibility while it is still cheap to report.

Check the two changed defaults explicitly. jit off and default_toast_compression on lz4 are the changes most likely to alter behavior without an error message. JIT going off can change the shape of a query plan you benchmarked; on most workloads it makes things faster, which is why the default changed, but "most" is not "yours." Read them off your own server with the SHOW statements above rather than trusting a blog post, including this one.

Plan around November 19, but hold the date loosely. There is a real date now, in a real release announcement, which is a different situation from last month. It is still conditional: the announcement reserves the right to delay or add another candidate, and this cycle has already moved its GA target once after putting it in writing. The honest read is that November 19 is likely and late November is near certain. The signal to watch for is RC 2 on November 12. If it ships on time and quietly, the date holds; if it slips or a third candidate appears, your window moves with it. So book the maintenance window for late November with a week of slack in it, and schedule the work that has to happen before the upgrade now, while there are five weeks left to do it in.

If you want a 19 instance to point CI at while you wait, create one on Layerbase and pick 19.0.0-beta.3 from the version picker. I will update this post when RC 2 lands on November 12, and again at GA.