PostgreSQL 18 new features: what changed since PostgreSQL 17 and should you upgrade?
PostgreSQL 18 new features center on one big architectural shift — a native asynchronous I/O subsystem — plus skip scans on multicolumn B-tree indexes, virtual generated columns by default, OLD/NEW row access in RETURNING, temporal primary keys, and built-in OAuth 2.0 authentication. PostgreSQL 18 shipped on September 25, 2025, and as of July 2026 the current patch release is 18.4. Nine months of production data now exist, and the short answer is: yes, most teams should upgrade, but the "3x faster" headline number needs context before you plan a migration around it.
PostgreSQL isn't a niche choice anymore — 55.6% of developers reported using it in the 2025 Stack Overflow survey, up from 48.7% the year before, and it was the fastest-growing database on the DB-Engines ranking through the first half of 2026. That means a lot of teams are staring at this release and asking the same practical question: is this a "nice to have someday" upgrade, or does it change how you should architect a new project today?
This article covers what actually changed in PostgreSQL 18, what the async I/O numbers look like once you get past the marketing benchmark, how the new indexing and constraint features change real query patterns, and a concrete upgrade path — including a security reason to stop putting it off.
Key Takeaways
- PostgreSQL 18 (released September 25, 2025, current patch 18.4) adds async I/O, B-tree skip scans, virtual generated columns by default, OLD/NEW in
RETURNING, temporal constraints, and native OAuth 2.0.- Official benchmarks show up to 3x faster storage reads, but real-world 2026 production data shows 15-20% gains on cloud block storage (AWS EBS gp3) and 35-40% on local NVMe — the 3x figure is a best-case, not an average.
- Skip scans mean multicolumn indexes now serve queries that skip the leading column, which can retire redundant single-column indexes you built as workarounds.
- A May 2026 security release patched 11 CVEs (several rated CVSS 8.8) across every supported branch, including a password-timing side channel — a strong reason to be on a version you can patch quickly.
- PostgreSQL 13 reached end-of-life in November 2025, so teams still on 13 or older are now upgrading out of necessity, not preference.
What's actually new in PostgreSQL 18 vs PostgreSQL 17?
The single biggest change is the new asynchronous I/O subsystem, which lets PostgreSQL issue multiple read requests concurrently instead of blocking on each one — previously the norm only for a handful of specialized operations. Everything else in the release is smaller but still meaningfully changes day-to-day query and schema design.
Asynchronous I/O (AIO). PostgreSQL 18 introduces a new io_method parameter controlling whether reads are dispatched synchronously, through background I/O workers, or directly to the kernel via io_uring on Linux. According to the official PostgreSQL 18 release announcement, this new I/O subsystem "has demonstrated up to 3x performance improvements when reading data." AIO currently covers sequential scans, bitmap heap scans, and vacuum — it doesn't yet touch every code path, so don't expect a blanket 3x on an OLTP workload dominated by index lookups.
B-tree skip scan. Multicolumn B-tree indexes in PostgreSQL 17 and earlier were mostly useless if your query's WHERE clause skipped the leading column. PostgreSQL 18 can now "skip scan" past that gap, meaning an index on (tenant_id, created_at) can now serve a query that filters only on created_at — something that used to force a sequential scan or a second dedicated index.
Virtual generated columns by default. Generated columns in PostgreSQL 18 are computed at query time rather than stored on disk unless you explicitly ask for STORED. This cuts write amplification for tables with several derived columns, at the cost of a bit more CPU on read.
OLD/NEW values in RETURNING. INSERT, UPDATE, DELETE, and MERGE statements can now reference both the previous and new row values in a single RETURNING clause — previously you needed a trigger or a second round trip to diff a row before and after a write.
Temporal constraints. PostgreSQL 18 adds WITHOUT OVERLAPS for PRIMARY KEY/UNIQUE constraints and PERIOD for FOREIGN KEY constraints, letting the database itself enforce "no two rows for the same resource can have overlapping time ranges" — a rule teams previously bolted on with exclusion constraints or application logic.
Native OAuth 2.0 authentication. PostgreSQL can now authenticate connections against an OAuth 2.0 provider directly, simplifying SSO integration that used to require an external proxy like pgbouncer with a custom auth layer, or LDAP gymnastics.
pg_upgrade improvements. Upgrades run faster on databases with many objects, checks can run in parallel via --jobs, and a new --swap flag swaps data directories instead of copying or cloning them — relevant below.
| Feature | PostgreSQL 17 | PostgreSQL 18 |
|---|---|---|
| I/O model | Synchronous, one request at a time per backend | Async I/O via io_method (sync / worker / io_uring) |
| Multicolumn index on skipped leading column | Sequential scan | Skip scan uses the index |
| Generated columns default | Stored on disk | Virtual (computed at query time) |
RETURNING clause |
New row values only | OLD and NEW row values |
| Overlapping time-range constraints | Exclusion constraints / app logic | Native WITHOUT OVERLAPS / PERIOD |
| SSO auth | LDAP / external proxy workarounds | Native OAuth 2.0 |
pg_upgrade |
Sequential checks, copy/clone/link | Parallel --jobs, --swap directory swap |
| UUID generation | gen_random_uuid() only |
Adds uuidv7() (timestamp-ordered), uuidv4() alias |
Is PostgreSQL 18's async I/O actually 3x faster?
The honest answer is: on the specific storage-bound read benchmark PostgreSQL's own team ran, yes — but "up to 3x" is a ceiling from a favorable case, not a typical production result. Real-world 2026 deployment data puts realistic gains between 15% and 40% depending on your storage layer.
According to production benchmarking covered by pganalyze, async I/O on AWS EBS gp3 cloud storage delivers roughly 15-20% throughput gains for read-heavy workloads, with P95 read latency dropping from around 8ms to 5ms on a 500GB working set. On local NVMe storage — AWS i4i instances with instance-store NVMe — throughput improvements reach 35-40% once io_method and worker counts are properly tuned. In practice, the gap between "up to 3x" and "20% on cloud disks" comes down to how I/O-bound your workload actually is: sequential scans and vacuum on a dataset larger than RAM benefit the most, while a cache-friendly OLTP workload that mostly hits shared_buffers won't see much difference at all.
If your workload is analytics-heavy, does large sequential scans, or runs big vacuum/maintenance windows against data that doesn't fit in memory, async I/O is worth testing seriously. If you're running a small OLTP app where the working set already lives in cache, don't expect the upgrade alone to move your latency graphs much — the win there comes from skip scans and better query plans, not I/O concurrency.
PostgreSQL 18 vs PostgreSQL 17: which query patterns actually change?
Skip scans and generated-column changes affect how you should design new indexes and generated columns, but they rarely require rewriting existing queries — the planner picks the better plan automatically once you're on 18. The practical impact shows up in index design more than in SQL syntax.
Before PostgreSQL 18, a common workaround for the "leading column" B-tree limitation was maintaining two indexes: one on (tenant_id, created_at) and a redundant one on (created_at) alone, just so date-range queries without a tenant filter could use an index. With skip scan, that second index is often no longer necessary, which directly reduces write overhead and storage — every index you drop is one less structure to update on every INSERT. It's worth auditing your pg_indexes after upgrading to see which single-column indexes have become redundant.
The temporal constraints matter most for booking systems, resource scheduling, and any table where "no two active rows can overlap in time" is a real business rule. In practice, replacing a hand-rolled exclusion constraint or an application-level check with WITHOUT OVERLAPS removes an entire class of race-condition bugs, because the database enforces it atomically at the constraint level instead of relying on read-then-write logic in your app.
If you're running vector search on top of Postgres via pgvector, async I/O's sequential-scan and vacuum improvements are relevant background context — large ANN index builds and maintenance windows both do heavy sequential I/O, so the same tuning discussion applies even though pgvector itself isn't a named beneficiary in the release notes.
How do you upgrade from PostgreSQL 17 to PostgreSQL 18?
For most self-hosted deployments, pg_upgrade remains the fastest path, and PostgreSQL 18 makes it noticeably quicker on databases with many tables via parallel checks and the new --swap flag. Managed-service users (RDS, Cloud SQL, Supabase, etc.) mostly just click "upgrade" and let the provider run an equivalent process, but the pre-upgrade homework is identical either way.
- Back up everything first. Run a full
pg_dumpallor use your provider's snapshot mechanism before touching anything — this is not optional for a major-version jump. - Audit extensions. Check that PostGIS,
pg_partman, TimescaleDB,pg_cron, and anything else you rely on has a PostgreSQL 18-compatible build before you commit to a date. - Install PostgreSQL 18 binaries alongside your existing instance. Don't remove the old version until the upgrade is verified.
- Run
pg_upgrade --checkfirst, and pass--jobs Nto parallelize the compatibility checks on larger schemas — this is the part PostgreSQL 18 sped up. - Choose your method:
pg_upgrade(fastest, some downtime), dump/restore (cleanest, more downtime), or logical replication (near-zero downtime, more setup work) depending on your uptime requirements. - Run the upgrade, then immediately run
ANALYZEon the new cluster — query plans will be wrong until statistics are rebuilt. - Verify: check
SELECT version();, compare object counts against the old cluster, and run your critical queries before cutting traffic over.
For the official, authoritative version of this process, see the PostgreSQL upgrading documentation and the pg_upgrade reference.
-- Quick sanity checks to run immediately after upgrading
SELECT version();
-- Rebuild planner statistics — critical after any major upgrade
ANALYZE;
-- Confirm which io_method is active (new in PostgreSQL 18)
SHOW io_method;
Should you upgrade to PostgreSQL 18 in 2026, or wait?
Yes, you should plan the upgrade now, and there's a security reason to not let it slide: on May 14, 2026, the PostgreSQL project shipped patches for 11 CVEs across every supported branch, several rated CVSS 8.8, including a password-comparison timing side channel and a symlink-following bug in pg_basebackup/pg_rewind. Being current on the latest major version doesn't exempt you from patching, but teams that upgrade major versions regularly tend to also stay current on point releases — the two habits reinforce each other.
There's also a forcing function for anyone still behind: PostgreSQL 13 reached end-of-life on November 13, 2025, meaning it no longer receives security or bug fixes at all under the community's five-year support policy. If you're on 13 or older, this isn't really an "upgrade to 18 for the features" decision anymore — it's a "get onto a supported version, and 18 is the newest one" decision. If you're already on 16 or 17, the calculus is softer: async I/O and skip scans are real wins for I/O-heavy and multicolumn-index-heavy workloads, but nothing in this release is an emergency unless your workload specifically matches those patterns.
One place this matters even if you're not managing Postgres directly: if you're evaluating Supabase vs Firebase for a new project, Supabase's entire value proposition rests on top of Postgres, so which major version they run underneath affects what features and performance you inherit for free. It's worth checking which Postgres version your managed provider defaults new projects to before you assume you're already on 18.
Frequently Asked Questions
When was PostgreSQL 18 released? PostgreSQL 18 was released on September 25, 2025. As of July 2026, the current patch release is PostgreSQL 18.4, which also includes a May 2026 security update patching 11 CVEs.
Is PostgreSQL 18 faster than PostgreSQL 17? Yes, primarily due to the new asynchronous I/O subsystem, which official benchmarks show delivering up to 3x faster storage reads. Real-world 2026 production data shows more modest but still meaningful gains — roughly 15-20% on cloud block storage like AWS EBS and 35-40% on local NVMe storage.
What is the biggest new feature in PostgreSQL 18?
The asynchronous I/O (AIO) subsystem is the headline feature, letting PostgreSQL issue multiple concurrent read requests via a new io_method setting instead of blocking on each I/O operation sequentially, currently covering sequential scans, bitmap heap scans, and vacuum.
Do I need to change my queries after upgrading to PostgreSQL 18? No — features like B-tree skip scans and the improved query planner work automatically once you're running PostgreSQL 18. You may want to review and drop redundant single-column indexes that were previously workarounds for the skip-scan limitation, but that's an optimization, not a requirement.
Is it safe to upgrade straight from PostgreSQL 13 to PostgreSQL 18?
Yes, pg_upgrade supports jumping multiple major versions directly, and this is now urgent rather than optional since PostgreSQL 13 reached end-of-life in November 2025 and no longer receives security patches.
Does PostgreSQL 18 support OAuth login? Yes, PostgreSQL 18 adds native OAuth 2.0 authentication support, making single sign-on integration simpler than the LDAP or external-proxy workarounds required in PostgreSQL 17 and earlier.
The verdict
PostgreSQL 18 is a genuinely useful release, not just a version-number bump: async I/O, skip scans, and native OAuth are the kind of changes that quietly remove workarounds teams have been carrying for years. But don't upgrade chasing the "3x faster" headline alone — that number is a best case for storage-bound sequential reads, and most teams will see something closer to 15-40% depending on their storage layer and how I/O-bound their workload actually is.
The clearer driver in mid-2026 isn't the feature list — it's support lifecycle. If you're on PostgreSQL 13 or older, you're already unsupported and need to move regardless of which version you land on, so it might as well be 18. If you're on 16 or 17, treat this as a normal, low-drama major upgrade: back up, check extension compatibility, test on staging, and go. For teams building anything vector-search-adjacent, it's also worth revisiting our pgvector vs Pinecone vs Qdrant comparison — the storage engine underneath all of them just got a meaningful I/O upgrade, and for open-source infrastructure decisions generally, our Valkey vs Redis breakdown covers the same "is the open-source fork worth the migration" question from a different angle.
Postgres isn't trying to reinvent itself with every release — and that's exactly why it keeps winning.