PostgreSQL 18, released on September 25, 2025, includes major features focused on performance, manageability, and developer experience.
This is a landmark release. It’s not just an incremental update; it’s a fundamental shift that directly addresses some of the long-standing performance, operational, and development pain points in high-scale Postgres environments.
This release delivers on two major fronts: raw I/O performance gains through asynchronous operations, and critical quality-of-life and indexing improvements that smooth the path for both developers and database administrators. If your business runs on Postgres, upgrading to version 18 is a move that will pay immediate and substantial dividends.
Game-Changing Performance: Asynchronous I/O (AIO) 🚀
The single most consequential change in PostgreSQL 18 is the introduction of a new Asynchronous I/O (AIO) subsystem for read operations. For decades, Postgres relied on synchronous I/O, meaning a single backend process would issue a read request and then simply wait for the disk or operating system (OS) to return the data before doing anything else. In modern cloud and virtualized environments where storage latency is a factor, this translates directly to wasted CPU cycles and reduced throughput.
Postgres 18 changes this paradigm. AIO allows the database to issue multiple read requests concurrently, using those former idle cycles to process other work. This drastically improves overall throughput and latency for I/O-bound workloads.
The Benchmark Advantage: Up to 3x Faster Reads
Initial benchmarks on high-latency storage (like network-attached storage in cloud environments) have demonstrated performance gains of up to 3x for cold reads.
Sequential Scan (Cold Read)
Postgres 17 (Sync I/O): ∼7.5 seconds
Postgres 18 (AIO/io_uring): ∼2.5 seconds
Improvement: ∼3.0× Faster
Bitmap Heap Scan (Index Lookup)
Postgres 17 (Sync I/O): ∼5.0 seconds
Postgres 18 (AIO/io_uring): ∼2.0 seconds
Improvement: ∼2.5× Faster
VACUUM (Maintenance)
Postgres 17 (Sync I/O): ∼15 seconds
Postgres 18 (AIO/io_uring): ∼8 seconds
Improvement: ∼1.9× Faster
Note: These numbers are illustrative of gains reported in testing on cloud-based VMs with high I/O latency, which benefits most from AIO. Actual results vary by hardware and workload.
DBA Impact: The io_method GUC
DBAs now have the power to configure this behavior via the new io_method GUC (Grand Unified Configuration):
- io_method = worker (Default): Uses a pool of background I/O workers to handle requests asynchronously. This is the new, cross-platform default.
- io_method = io_uring (Linux Only): Leverages the high-performance io_uring interface in modern Linux kernels (5.1+). This offers the lowest overhead and best results.
- io_method = sync: Maintains the old, synchronous behavior, useful for comparison or troubleshooting.
Real-World Use Case: A large e-commerce platform running nightly batch analytics involving massive sequential table scans to generate reports. By enabling io_uring on their Linux hosts, they experience a 60% reduction in nightly report generation time, freeing up resources for their critical daytime OLTP traffic.
Closing the Indexing Gap: The UUIDv7 Revolution
For years, developers have been torn between using auto-incrementing integers (BIGSERIAL) and globally unique identifiers (UUIDs) for primary keys. UUIDs offer distributed uniqueness and security, but the most common type, UUIDv4 (random-based), leads to severe B-tree index fragmentation and poor write performance because new data is inserted randomly across the index structure.
PostgreSQL 18 introduces native support for UUID version 7 (uuidv7()), which solves this problem completely.
The Benchmark Advantage: Write Performance Like BIGSERIAL
UUIDv7 is a time-ordered UUID. Its first 48 bits encode a Unix timestamp, ensuring that new IDs are always sequentially inserted at the end of the index. This behavior is virtually identical to an auto-incrementing integer, but you retain the 128-bit global uniqueness of a UUID.
Bulk Insert Time
BIGSERIAL (Auto-Increment): ∼3 min
UUIDv7 (Postgres 18): ∼3.5 min
UUIDv4 (Random): ∼15 min
Index Size
BIGSERIAL (Auto-Increment): ∼200 MB
UUIDv7 (Postgres 18): ∼250 MB
UUIDv4 (Random): ∼800 MB
Page Splits
BIGSERIAL (Auto-Increment): Minimal
UUIDv7 (Postgres 18): Minimal
UUIDv4 (Random): Extremely High
The takeaway is profound: You can now use UUIDs as primary keys in distributed systems without sacrificing OLTP write performance.
Example Code:
-- Generate the new, index-friendly UUIDv7
SELECT uuidv7();
-- Create a table with an optimized UUID PK
CREATE TABLE events (
id uuid DEFAULT uuidv7() PRIMARY KEY,
payload jsonb
);
DBA & Operational Excellence
Postgres 18 includes crucial features that make the life of a DBA significantly easier, particularly around major version upgrades and query analysis.
Seamless Major Version Upgrades
Historically, one of the most frustrating aspects of a major version upgrade (e.g., v17 to v18) using pg_upgrade was the performance dip immediately after the switch. This was because the query planner’s optimizer statistics were not carried over, forcing the system to re-run ANALYZE and re-learn the data distribution on a live, busy system.
- New in v18: The pg_upgrade utility now retains planner statistics.
- Advantage: The upgraded cluster starts with a fully optimized query plan cache. There is no longer a mandatory post-upgrade performance degradation period, making major version upgrades much safer and less disruptive for mission-critical applications.
Enhanced Observability: EXPLAIN ANALYZE Default
For years, the gold standard for tuning required the tedious addition of BUFFERS and TIMING to your EXPLAIN ANALYZE command to get the full picture of I/O.
- New in v18: EXPLAIN ANALYZE now automatically includes buffer usage by default.
- Advantage: This small change forces better habits and saves time, ensuring developers and DBAs get the critical I/O usage data they need to diagnose bottlenecks with less effort.
Developer Productivity Features
Postgres 18 introduces clean, powerful SQL features that simplify application logic and improve data modeling.
Virtual Generated Columns (VIRTUAL is Default)
Generated columns (computed values) were introduced in a previous version but were always STORED (computed on write and occupying disk space), which required a full table rewrite when added.
- New in v18: The new VIRTUAL option is now the default.
- Advantage: Virtual columns are computed on read and occupy zero disk space in the table heap. Adding a virtual column is an instantaneous metadata change (no table rewrite), making schema migrations much safer and faster.
Example Code:
CREATE TABLE orders (
price DECIMAL,
quantity INT,
-- VIRTUAL is the default now, no STORED keyword needed
subtotal DECIMAL(10, 2) GENERATED ALWAYS AS (price * quantity)
);
-- Adding this column is instant and uses no disk space.
Full OLD and NEW Support in RETURNING
Prior to v18, the RETURNING clause on DML statements was limited: INSERT and UPDATE could only return the NEW row, and DELETE could only return the OLD row. Capturing both before and after states for audit logs often required triggers or two separate queries.
- New in v18: Use the aliases OLD and NEW explicitly in the RETURNING clause for all DML commands.
- Advantage: This allows for single-query atomic audit logging and change tracking.
Example Code:
UPDATE products
SET price = price * 1.10
WHERE price <= 99.99
RETURNING
OLD.name AS product_name,
OLD.price AS old_price,
NEW.price AS new_price,
NEW.price - OLD.price AS price_change;
Smarter Query Optimization: B-tree Skip Scan
The B-tree index is the workhorse of relational databases, but it always had a limitation: a multicolumn index ((A, B, C)) could only be used efficiently if the query filtered on the leading column (A).
- New in v18: The optimizer can now use Skip Scan lookups.
- Advantage: For indexes where the leading column has low cardinality (e.g., status in a (status, created_at) index), the planner can efficiently “skip” over the distinct values of the leading column to search on the second column, allowing a single index to be used for more query patterns than ever before. This is an automatic, transparent performance win for many existing tables.
Conclusion
The combination of Asynchronous I/O providing raw, underlying performance gains, UUIDv7 solving the key index fragmentation issue for distributed applications, and retaining planner statistics for painless upgrades makes this version an unparalleled success for both large-scale operations and modern application development.
It further solidifies PostgreSQL’s standing as the most advanced and feature-rich open-source relational database in the world.
PostgreSQL 18 is a must-have upgrade.
To keep your finger on the pulse of these critical updates, to get the deeper dives, benchmark breakdowns, and hands-on different tutorials that will help you hit the ground. Strike while the iron is hot and subscribe to my channel now!
Let’s conquer the next topic together.
Top comments (0)