← Back to list

The Secret Weapon for Performance Boosting — Asynchronous Operations in the Kernel: io_uring

explanation of io_uring

vic · 2025-10-06 11:01 · 2 claps · 3.1 min read paywalled
#linux-kernel #iouring #asynchronous
Open on Medium ↗
Wiki topics: 🔓 · Open Source

The Secret Weapon for Performance Boosting — Asynchronous Operations in the Kernel: io_uring

In software development, asynchronous operations are often used to improve API response time.

For instance, when a user logs in successfully, the API may queue the “send email” request for another thread to handle. The login API can return the response immediately without waiting for the email to be sent, allowing the frontend to receive the token faster and proceed with the next actions.

Beyond API development, the Linux kernel also employs asynchronous operations to enhance performance — notably through io_uring.

How Do Asynchronous Operations Improve Kernel Performance?

When a user-space process interacts with hardware (e.g., network or file I/O), it sends a system call request to the kernel, which then communicates with the hardware.

During this time, the process enters an I/O wait state and is removed from the CPU by the kernel scheduler so that other processes can execute. If all processes enter I/O wait, the CPU becomes idle.

Additionally, if a user-space process executes multiple I/O operations (e.g., reading multiple files), it traditionally needs to make multiple system calls and wait for each I/O to complete before issuing the next — an inefficient process.

To address these issues, Linux introduced io_uring, a mechanism that allows multiple I/O operations to be submitted to the kernel queue with a single system call and processed asynchronously.

With io_uring:

  • The process no longer enters I/O wait and can continue executing other instructions, preventing CPU idling.
  • Multiple I/O requests can be submitted in one go, reducing context switches.
  • Hardware concurrency (e.g., SSD multi-channel reads) can be fully utilized.

How Does io_uring Reduce System Calls?

The io_uring_setup() system call initializes the io_uring structure, which includes two ring buffers:

  • Submission Queue (SQ) — where the user-space process places I/O requests (e.g., read, write).
  • Completion Queue (CQ) — where the kernel places notifications when I/O operations are complete.

After initialization, the process uses mmap() to map both queues into user space. It can then directly write to SQ and read from CQ. Once multiple read requests are placed in SQ, the process calls **io_uring_enter()** just once to notify the kernel to process all pending requests.

Originally, each read() required a separate system call. With io_uring, after setup and mapping, multiple reads can be handled with just one call to io_uring_enter().

How Does a Process Read Data from CQ?

Traditionally, read() passes a byte array pointer to the kernel, which validates it. When hardware returns data to the kernel’s page cache, the kernel uses copy_to_user to copy it into the user-space buffer.

With io_uring, a read request becomes an SQE (submission queue entry) structure placed into SQ. Each SQE contains:

  • The byte array pointer.
  • A **user_data** field, representing the request ID.

When the process reads a CQE (completion queue entry) from CQ, it includes the same user_data — allowing the process to identify which request has completed and directly access the corresponding memory buffer.

Similarly, for write operations, the kernel uses copy_from_user to copy data from user space into the kernel’s page cache before writing to disk.

Can We Eliminate Copying Altogether?

Copying large data blocks is expensive. If the kernel can already access user-space memory, can hardware directly read/write to it — skipping copy_to_user and copy_from_user?

Yes — by using Zero-Copy I/O.

When a file is opened with the **O_DIRECT flag, the hardware (e.g., disk) can use DMA (Direct Memory Access)** to write directly into memory without CPU involvement.

With io_uring, you can call **io_uring_register_buffers** to register a specific memory region in user space. The kernel validates it once, then all subsequent I/O operations can directly use this region, bypassing both copying and repeated validation — greatly improving performance.

Are There More Ways to Speed Up io_uring?

Yes, two major optimizations exist:

Eliminate the need for io_uring_enter()

  • By enabling **IORING_SETUP_SQPOLL**, the kernel spawns a thread that continuously polls the SQ for new requests.
  • The user process no longer needs to call io_uring_enter() — reducing system call overhead.

Eliminate hardware interrupt dependency

  • Normally, when the kernel thread sends a request to hardware, it waits until the hardware sends an interrupt signal upon completion.
  • This involves scheduler context switching.
  • With **IORING_SETUP_IOPOLL, the kernel instead polls the hardware driver** to check for completion, avoiding interrupts and context switches — achieving faster I/O completion updates.

However, these optimizations consume more CPU resources, so they are best suited for I/O-bound workloads rather than CPU-bound ones.

Real-World Use Case: PostgreSQL 18

Starting from version 18, PostgreSQL introduced asynchronous I/O with two modes:

  • Worker (default): I/O operations (read()/write()) are delegated to a separate process via a queue. Performance improvement for read-heavy queries: ~1.5×.
  • io_uring mode: I/O operations are handled through io_uring instead of traditional system calls. Performance improvement for read-heavy queries: ~2.7×.

However, PostgreSQL also noted that with io_uring enabled, **EXPLAIN ANALYZE may no longer report accurate I/O timings**, since I/O operations are fully asynchronous.


메타데이터
post_id
6345c81be936
slug
the-secret-weapon-for-performance-boosting-asynchronous-operations-in-the-kernel-io-uring-6345c81be936
url
https://medium.com/@vicxu/the-secret-weapon-for-performance-boosting-asynchronous-operations-in-the-kernel-io-uring-6345c81be936
canonical_url
https://medium.com/@vicxu/the-secret-weapon-for-performance-boosting-asynchronous-operations-in-the-kernel-io-uring-6345c81be936
author_url
https://medium.com/@vicxu
status
ok
fetched_at
2026-07-17 08:11:56