← lab notes

io_uring vs mmap: a null result, honestly spent

2026-05-30 · null result

TL;DR — For sequential full-tape ingest, mmap + madvise(SEQUENTIAL) beat my io_uring implementation. The ring is a brilliant API. It was also the wrong tool for this exact workload, and I only know that because I measured it.

Why I expected a win

io_uring promises syscall-free submission, batched completions, and kernel-side readahead you control. A tape parser that eats hundreds of megabytes per second sounded like the poster child.

What actually happened

The workload is a single hot sequential scan of a file that fits comfortably in page cache after first touch. mmap turns that into pure page-fault-then-memory-read with the kernel's readahead already tuned for exactly this pattern. My ring added completion-queue bookkeeping and buffer management on top of work the kernel was already doing for free.

What I kept

Null results don't get frontpage treatment anywhere else, so they get it here.