Aiven Blog

Exploring why PostgreSQL 18 put asynchronous I/O in your database

Alexander Fridriksson

|RSS Feed

Alexander does product marketing for databases at Aiven. Throughout his career he's worked across marketing, sales, analytics, data engineering and more.

For years, PostgreSQL relied on synchronous I/O, meaning that when the database needed data from disk, each read operation was a blocking system call. The database process would therefore pause and wait for the data retrieval before moving to the next task.

Synchronous I/O works well for local storage, but our database needs have changed drastically since then, resulting in this architecture creating significant bottlenecks when storage has higher latency. That is common with network-attached cloud storage, such as Amazon EBS.

Asynchronous I/O (AIO) fundamentally changes this by allowing Postgres to submit multiple read requests concurrently, enabling I/O and computation to overlap. This change allows the database to control read-ahead decisions based on query plans, resulting in more predictable and higher-throughput I/O behavior.

The three I/O methods in PostgreSQL 18

PostgreSQL 18 introduces the io_method configuration parameter to control how AIO works.

I/O MethodUse caseExplaination
workerAsynchronous I/O (default)A background worker processes I/O requests, allowing the main process to continue execution. This is the default setting in PostgreSQL 18.
syncSynchronous I/OIf you want to keep the same behavior as PostgreSQL 17 with blocking reads, you can set it to sync instead.
io_uringSpecific to LinuxCreates a shared ring buffer that minimizes system call overhead. While this usually gives the best performance, it's important to keep in mind that you might be opening yourself up to security risks by using io_uring. To use it, you would also need your PostgreSQL to be built with the --with-liburing flag.

Configuring and testing asynchronous I/O

AIO benefits read-heavy workloads, such as sequential scans of tables exceeding available memory or large index range scans. However, write operations are currently only synchronous.

As always, you can create a free Aiven for PostgreSQL instance with the Aiven CLI to try things out for yourself.

Loading code...

Check the configuration

Loading code...
namesettingshort_desc
effective_io_concurrency16Number of simultaneous requests that can be handled efficiently by the disk subsystem.
io_max_concurrency64Max number of IOs that one process can execute simultaneously.
io_methodworkerSelects the method for executing asynchronous I/O.
io_workers3Number of IO worker processes, for io_method=worker.

As we can confirm from the query output, the io_method is set to the default worker method, so we don’t need to do anything to make it asynchronous. But if we wanted it to behave like PostgreSQL 17, we could change it to be synchronous.

Loading code...

One thing to keep in mind is that after modifying the io_method, you might have to restart PostgreSQL if the result of the pending_restart is true.

Loading code...

We also saw previously that the default effective_io_concurrency is 16, but we can increase or decrease it if needed.

Loading code...

Creating data for our test

With AIO you could expect to see a big difference when data is read directly from disk, but not necessarily when reading from the buffer cache, as the process might never be waiting for high-latency I/O.

Therefore, we need data that is larger than our shared_buffers for a proper test.

Loading code...

The final thing we need to do for a proper test is to clear the stats and buffer cache for our async_crab_rave table. For convenience, we can use the pg_prewarm extension to help us with this.

Loading code...

Running the tests

For our tests, let’s compare the new asynchronous worker method against the old synchronous sync method.

Loading code...

For our comparison, we’ll need to switch sync and disable effective_io_concurrency by setting it to 0.

Loading code...

You should expect a solid performance improvement, with the most significant improvements coming from high-latency and read-heavy workloads.

Monitoring asynchronous activity

PostgreSQL 18 introduces the pg_aios system view to provide insights into asynchronous I/O operations and requests currently in progress:

Loading code...

You can also use pg_stat_activity to view information about background worker processes by searching for the io worker backend type.

Loading code...

Summary

PostgreSQL 18 introduced Asynchronous I/O (AIO) primarily to improve database performance for read-heavy workloads, particularly in environments with higher storage latency like cloud platforms. This feature allows the database to initiate multiple read operations concurrently without waiting for each one to complete individually, overcoming the bottlenecks of previous synchronous I/O models.

Postgres 18 comes with a lot more exciting features, and you can leverage these exciting new features and explore what else Postgres 18 has to offer with Aiven today.


Stay updated with Aiven

Subscribe for the latest news and insights on open source, Aiven offerings, and more.

Related resources