Glitch & Glow
DataMay 14, 20261 min read

Postgres 18 made async I/O the default and nobody noticed

The most consequential database release of the year shipped without a keynote. Async I/O is now on by default and your read-heavy workloads just got 40% faster.

By The Editors

The Postgres 18 release notes are 32 pages long. Page 6 mentions, in a single bullet, that asynchronous I/O via io_uring is now enabled by default on Linux.

That is the headline. Everything else is a footnote.

What changed

For most of its history Postgres has issued one I/O request at a time per backend, waiting for each to complete before issuing the next. On modern NVMe storage that left an embarrassing amount of throughput on the table — the kernel can comfortably handle thousands of in-flight requests, and the database was using one.

Postgres 18 ships a generalized async I/O subsystem with io_uring as the first backend. Sequential scans, index scans, and bitmap heap scans can now batch reads. The team has published benchmark numbers showing 30-45% improvements on read-heavy analytical workloads on consumer NVMe and up to 2x on enterprise storage.

Why this matters

Postgres has spent a decade closing the gap with proprietary databases on workloads that were historically Oracle's home turf. This release closes most of what was left. For analytics-on-Postgres setups — every modern dbt shop, every "we'll worry about a warehouse later" startup — the bill just got smaller.

What to watch

The default is on, but the kernel requirement is real: you need a reasonably modern Linux. RHEL 8 and earlier kernels will silently fall back to the legacy path. Check pg_stat_io after upgrading to confirm you're actually using the new backend.

Also: write-heavy OLTP workloads see modest improvements, not the dramatic ones. If your read/write ratio is 50/50 and you were hoping this release would fix your queue latency, it won't. Different problem.

#postgres#databases#performance#io_uring

Discussion

Comments live on GitHub Discussions via giscus. A GitHub account is required to post.

Comments are powered by giscus.

Configure NEXT_PUBLIC_GISCUS_REPO_ID and NEXT_PUBLIC_GISCUS_CATEGORY_ID in .env.local to enable.