This post is maintained by Bytebase, an open-source database DevSecOps tool that can manage PostgreSQL. We will constantly update this post to include the latest Postgres 18.x releases.
| Update History | Comment |
|---|---|
| 2025/05/13 | Initial version. |
PostgreSQL 18 ships on September 25, 2025. The release moves on async I/O, UUIDv7, and a set of long-requested operational fixes — adding NOT NULL without a full table scan, virtual generated columns, RETURNING with old/new aliases, and a faster pg_upgrade path. This post walks each feature and what it changes for the people running these databases.
Release Timeline
- PostgreSQL 18 Beta 1: May 8, 2025
- PostgreSQL 18 Beta 2: July 17, 2025
- PostgreSQL 18 Beta 3: August 14, 2025
- PostgreSQL 18 RC 1: September 4, 2025
- PostgreSQL 18 Official Release: September 25, 2025
Asynchronous I/O
PostgreSQL 18 introduces an asynchronous I/O subsystem, selected by the new io_method server variable. Linux installations can use io_uring; every platform gets a worker-based fallback. The first wave covers reads — sequential scans, bitmap heap scans, and VACUUM. A new system view, pg_aios, exposes the file handles in flight.
DBA Note: Reads only at first. Write-heavy OLTP will not see a step change. The largest gains should land on cloud databases with network-attached storage, where I/O latency dominates wall-clock time. Re-run baseline benchmarks before assuming existing capacity numbers still hold, and watch for new failure modes specific to the chosen I/O method.
UUIDv7
The new uuidv7() function returns timestamp-ordered UUIDs. uuidv4() is now an alias for gen_random_uuid().
DBA Note: Time-ordered UUIDs reduce B-tree page splits and keep hot indexes warmer. For application primary keys generated outside the database, this closes a long-standing gap against sequence-based integers without giving up global uniqueness.
Improved EXPLAIN
EXPLAIN ANALYZE now includes BUFFERS by default. EXPLAIN ANALYZE VERBOSE adds WAL usage, CPU statistics, and per-row averages. EXPLAIN (WAL), VACUUM/ANALYZE (VERBOSE), and the autovacuum log all gain a full WAL buffer count.
DBA Note: BUFFERS by default lowers the bar for spotting cache misses during development. WAL and per-row averages in VERBOSE matter most when diagnosing replication lag and autovacuum throughput — both areas where the previous output left gaps.
NOT NULL constraints as NOT VALID
NOT NULL can now be added with NOT VALID, then validated separately:
ALTER TABLE table_name ADD CONSTRAINT constraint_name NOT NULL (column) NOT VALID;
ALTER TABLE table_name VALIDATE CONSTRAINT constraint_name;The initial ADD CONSTRAINT skips the table scan. Validation later runs under ShareUpdateExclusiveLock, so SELECT, INSERT, UPDATE, and DELETE proceed normally. The constraint still rejects new NULLs from the moment it is created.
Before Postgres 18, the equivalent pattern was the less obvious CHECK (column IS NOT NULL) NOT VALID.
DBA Note: Adding a NOT NULL on a multi-terabyte table no longer requires an ACCESS EXCLUSIVE lock for the duration of the scan. New rows are protected immediately; historical cleanup happens on your schedule. One fewer reason to book a maintenance window.
OLD/NEW values in RETURNING
RETURNING accepts changeable old and new aliases. INSERT ... ON CONFLICT can return prior values. UPDATE can return both old and new. DELETE can surface values produced by an ON DELETE row assignment.
DBA Note: Application code that needed before-and-after state previously read the row first or attached a trigger. The aliases fold that into the original statement, which removes a category of race conditions and a familiar set of trigger workarounds.
Virtual generated columns
Generated columns are now virtual by default — computed on read rather than stored. STORED remains available when materialization is required. Stored generated columns can now be logically replicated.
DBA Note: Disk and write overhead drop for derived columns that do not need persistence — concatenations, formatted output, simple arithmetic. Reads pay the compute cost on each access, so expressions that are expensive or sit on hot read paths should stay STORED. Logical replication of stored columns lines up with what downstream consumers typically expect.
Major version upgrades
The headline change for upgrade operators is preserved planner statistics. The newly upgraded cluster keeps its plans without waiting for ANALYZE to repopulate. pg_upgrade --jobs parallelizes pre-upgrade checks; --swap exchanges directories instead of copying, which is the difference between minutes and hours on large installations.
The 18 release also lands several incompatibilities. Time zone abbreviation handling, MD5 password deprecation, VACUUM/ANALYZE inheritance behavior, and COPY FROM end-of-file handling all changed. Each is small in isolation; together they are where existing automation tends to break.
DBA Note: Statistics persistence removes one of the most common post-upgrade incident patterns — query plans regressing under load while ANALYZE catches up. --swap is the lever to pull when copy time dominated past upgrade windows. Test the incompatibilities in staging; upgrades remain the place where the unread footnote causes pages.