io_uring is a clever new, high-performance interface for asynchronous I/O for Linux without the drawbacks of the aio set of APIs. In this 3-part article series, we look at how to use io_uring to get the most common programming tasks done under Linux. We write a series of programs of increasing complexity to slowly but steadily introduce the features of io_uring . While we will use liburing for the most part, we do explore the raw io_uring interface in part 1 so that we understand the interface at a low-level.

Here are the list of articles in this series and their summaries

Part 1: Introduction: In this article, we look at an introduction to io_uring and the programming interface it presents. We create 3 versions of an equivalent of the Unix cat utility. The first version, regular_cat , is built using synchronous readv() system calls. This serves as a reference for us to compare synchronous and asynchronous programming. The second version, cat_uring is functionally the same as the previous example, but is built using io_uring ‘s raw interface. The final version in this part, cat_liburing , is built with liburing , which provides a higher-lever interface to io_uring .

and the programming interface it presents. We create 3 versions of an equivalent of the Unix utility. The first version, , is built using synchronous system calls. This serves as a reference for us to compare synchronous and asynchronous programming. The second version, is functionally the same as the previous example, but is built using ‘s raw interface. The final version in this part, , is built with , which provides a higher-lever interface to . Part 2: Queuing multiple operations: the previous example serves as an introduction, we keep it simple on purpose queuing only one request at a time to process. In this part, we develop a file copying program, cp_liburing , in which is capable of queuing several requests so that io_uring can process them all in one go, with a single system call.

, in which is capable of queuing several requests so that can process them all in one go, with a single system call. Part 3: In this part, we develop a simple web server written using io_uring . Featuring ZeroHTTPd, a simple web server that uses io_uring exclusively to do all I/O. We see how to queue accept() , readv() and writev() operations using io_uring .

By building ZeroHTTPd, we culminate.

ZeroHTTPd index page

Source code

The full source code for all the examples is available here at Github.

A note on kernel versions

io_uring is a fairly new and rapidly evolving kernel subsystem. Please note that for the web server example, you’ll at least need to be running kernel version 5.5. Most distributions are not yet running that version or newer at the time of writing this. As for other examples, I’ve tested them on a machine running kernel version 5.3 and they run fine. The web server example was tested on Arch Linux which currently is based on kernel version 5.5.15.

About me

My name is Shuveb Hussain and I’m the author of this Linux-focused blog. You can follow me on Twitter where I post tech-related content mostly focusing on Linux, performance, scalability and cloud technologies.