{"slug": "io-uring", "name": "io_uring", "category": "os", "category_name": "Operating systems and desktop", "description": "", "recommenders": 6, "commenters": 17, "warners": 3, "score": 4.193, "rising": -1.96, "first": "2025-11-27", "latest": "2026-10-31", "why": "I would probably easily agree that io_uring in general is a better design", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 6, "neutral": 5, "compare": 3, "warn": 3}, "spark": [1, 0, 1, 0, 3, 0, 0, 1, 0, 0, 0, 0], "listed": true, "loved": [], "caveat": "", "short_quote": "I would probably easily agree that io_uring in general is a better design", "kind": "", "icon": false, "domain": "unixism.net", "github_repo": null, "official_url": "", "pricing": "", "aliases": ["io_uring", "io-uring"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 777844560, "item_id": 48615285, "url": "https://news.ycombinator.com/item?id=48615285", "by": "Cloudef", "date": "2026-06-20", "stance": "recommend", "quote": "For large zero-copy buffers, io_uring is king however.", "excerpt": "Quite depends, I had times when my posix emulation of io_uring (with poll, not epoll) was faster than io_uring. For large zero-copy buffers, io_uring is king however. Also io_uring is useful even for non asynchronous IO as it can implement chain of operations as single atomic operation (mkdir + open it for example). For something like networking, if you are maximizing packets per second, you'll hit kernel limits[1] v", "context": "", "use_case": "async I/O for large buffers", "switched_from": "", "story": "Epoll vs. Io_uring in Linux"}, {"id": 760475760, "item_id": 47529735, "url": "https://news.ycombinator.com/item?id=47529735", "by": "menaerus", "date": "2026-03-26", "stance": "recommend", "quote": "I would probably easily agree that io_uring in general is a better design", "excerpt": "> Also, it would be useful to test across different devices, since their behavior can vary significantly, especially when preconditioned or under corner-case workloads. Agreed. And from first-hand experience I know how painful this is, and how proving or disproving the hypothesis you have about certain wheel in the system can turn into a crazy rabbit hole, especially in the infrastructure software which due to ever i", "context": "", "use_case": "", "switched_from": "", "story": "io_uring, libaio performance across Linux kernels and an unexpected IOMMU trap"}, {"id": 756901264, "item_id": 47306329, "url": "https://news.ycombinator.com/item?id=47306329", "by": "ozgrakkurt", "date": "2026-03-09", "stance": "recommend", "quote": "https://docs.rs/io-uring/latest/io_uring/opcode/index.html", "excerpt": "https://docs.rs/io-uring/latest/io_uring/opcode/index.html You can click the source code link and read the code here. Macros aren\u2019t needed at all if every single operation isn\u2019t a different type.", "context": "", "use_case": "", "switched_from": "", "story": "A Grand Vision for Rust"}, {"id": 755796976, "item_id": 47237311, "url": "https://news.ycombinator.com/item?id=47237311", "by": "jauntywundrkind", "date": "2026-03-03", "stance": "recommend", "quote": "Absolutely fricking sick!!", "excerpt": "> This patch is trying to make io_uring customizable via BPF, promising better waiting and polling patterns https://lore.kernel.org/bpf/cover.1763031077.git.asml.silence@gmail.com/ Absolutely fricking sick!! The write up of use cases here is so so wildly neat. Please please please, make the new completion queue engine in the kernel programmable with eBPF!!", "context": "", "use_case": "Linux async I/O", "switched_from": "", "story": "What's new in Linux kernel for PostgreSQL"}, {"id": 755632992, "item_id": 47227062, "url": "https://news.ycombinator.com/item?id=47227062", "by": "nickelpro", "date": "2026-03-02", "stance": "recommend", "quote": "io_uring wasn't built just for kicks", "excerpt": "mmap is slow because stalling on page faults is slow. Your process stalls and sits around doing nothing instead of processing data you've read already. You can google the benchmarks if you like. io_uring wasn't built just for kicks. https://www.bitflux.ai/blog/memory-is-slow-part2/", "context": "", "use_case": "", "switched_from": "", "story": "Why does C have the best file API"}]}], "caveats": [{"label": "", "summary": "", "quotes": [{"id": 805133328, "item_id": 50320833, "url": "https://news.ycombinator.com/item?id=50320833", "by": "loeg", "date": "2026-10-31", "stance": "warn", "quote": "it has had repeated security problems since 2019", "excerpt": "The Redox article is underselling it somewhat. Part of the problem is Linux's historical syscall restriction systems (seccomp) did not (does not?) apply to io_uring, so io_uring is (was?) all or nothing on async versions of syscalls it implements. Also, io_uring is rapidly adding API surface compared to other parts of the kernel. With these factors combined, it has had repeated security problems since 2019 and has le", "context": "", "use_case": "", "switched_from": "", "story": "Redox: Ring Buffers Project Summary"}, {"id": 769101696, "item_id": 48068856, "url": "https://news.ycombinator.com/item?id=48068856", "by": "otterley", "date": "2026-05-08", "stance": "warn", "quote": "Google disabled io_uring on its production servers", "excerpt": "At one point, Google disabled io_uring on its production servers (https://security.googleblog.com/2023/06/learnings-from-kctf-vrps-42-linux.html) - I don't know whether this is still true, though. Perhaps a Google can confirm.", "context": "", "use_case": "", "switched_from": "", "story": "You gave me a u32. I gave you root. (io_uring ZCRX freelist LPE)"}, {"id": 756252592, "item_id": 47265787, "url": "https://news.ycombinator.com/item?id=47265787", "by": "jfindley", "date": "2026-03-05", "stance": "warn", "quote": "the list of vulnerabilities in io_uring over the past 12 months[2] is pretty staggering to me.", "excerpt": "There are a couple of notable examples of projects[0] and companies[1] that have got tired of it, and no longer use it. There's considerable difficulty these days extrapolating \"real\" vulnerabilities from kernel CVEs, as the kernel team quite reasonably feel that basically any bug can be a vulnerability in the right situation, but the list of vulnerabilities in io_uring over the past 12 months[2] is pretty staggering", "context": "", "use_case": "", "switched_from": "", "story": "Fast-Servers"}]}], "who": [], "tags": [], "use_cases": ["web server i/o", "async i/o for large buffers", "linux async i/o", "async i/o on linux"], "compared": [], "makers": [{"id": 797953968, "item_id": 49872123, "url": "https://news.ycombinator.com/item?id=49872123", "by": "jauntywundrkind", "date": "2026-09-28", "stance": "neutral", "quote": "tokio/io-uring support that I contributed", "excerpt": "I really wish reviewers would harp on FDP (Flexible Data Placement) and perhaps KV support. FDP supposedly somewhat ate ZNS as a spec, allegedly, but there might be gaps, reasons to keep ZNS. There's only a small little mention, if we are lucky, on the couple drives that have it (expensive enterprise flagships). It should be a regular sticking point, whether it's there or not. Without pressure it's not going to get r", "context": "", "use_case": "async I/O library", "switched_from": "", "story": "S3 Is the Future, S3 Is the Past"}], "threads": [{"url": "https://news.ycombinator.com/item?id=48613872", "title": "Epoll vs. Io_uring in Linux", "mentions": 2}, {"url": "https://news.ycombinator.com/item?id=46366998", "title": "Meta is using the Linux scheduler designed for Valve's Steam Deck on its servers", "mentions": 2}, {"url": "https://news.ycombinator.com/item?id=46073817", "title": "A programmer-friendly I/O abstraction over io_uring and kqueue (2022)", "mentions": 2}, {"url": "https://news.ycombinator.com/item?id=50274186", "title": "Redox: Ring Buffers Project Summary", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=49851693", "title": "S3 Is the Future, S3 Is the Past", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=49223105", "title": "Wireblast a 100 Gbps packet generator in Go using AF_XDP", "mentions": 1}], "sentiment_by_month": {"2025-11": {"neutral": 1, "recommend": 1}, "2025-12": {"compare": 2}, "2026-01": {"recommend": 1, "neutral": 2}, "2026-02": {}, "2026-03": {"recommend": 3, "warn": 1}, "2026-04": {"neutral": 1}, "2026-05": {"warn": 1}, "2026-06": {"recommend": 1, "neutral": 1}, "2026-07": {}, "2026-08": {"compare": 1}, "2026-09": {}, "2026-10": {"warn": 1}}, "quotes": [{"id": 805133328, "item_id": 50320833, "url": "https://news.ycombinator.com/item?id=50320833", "by": "loeg", "date": "2026-10-31", "stance": "warn", "quote": "it has had repeated security problems since 2019", "excerpt": "The Redox article is underselling it somewhat. Part of the problem is Linux's historical syscall restriction systems (seccomp) did not (does not?) apply to io_uring, so io_uring is (was?) all or nothing on async versions of syscalls it implements. Also, io_uring is rapidly adding API surface compared to other parts of the kernel. With these factors combined, it has had repeated security problems since 2019 and has le", "context": "", "use_case": "", "switched_from": "", "story": "Redox: Ring Buffers Project Summary"}, {"id": 787782657, "item_id": 49236416, "url": "https://news.ycombinator.com/item?id=49236416", "by": "touisteur", "date": "2026-08-09", "stance": "compare", "quote": "A lot of the socket featureset of io_uring seems available in AF_XDP", "excerpt": "I half-wished I'd get Cunningham's law-ed here. I read a bit more and there seems to be some support for tcp and udp offload, https://netdevconf.info/0x17/sessions/talk/tcp-offload-via-af_xdp-sockets-not-your-grandmothers-tcp-offload.html but I haven't checked how easy it is to use. A lot of the socket featureset of io_uring seems available in AF_XDP https://docs.kernel.org/networking/af_xdp.html which shows lots of ", "context": "", "use_case": "", "switched_from": "", "story": "Wireblast a 100 Gbps packet generator in Go using AF_XDP"}, {"id": 777859792, "item_id": 48616237, "url": "https://news.ycombinator.com/item?id=48616237", "by": "thomashabets2", "date": "2026-06-20", "stance": "neutral", "quote": "I want to sendfile with io_uring, but that's not supported yet.", "excerpt": "I've not yet tested the shared buffers for my io uring based web server, but that's because instead of reading from a file and writing, i send directly from a mmaped region. But really, I want to sendfile with io_uring, but that's not supported yet. My writeup, with extra buzzwords like Rust and kTLS: https://blog.habets.se/2025/04/io-uring-ktls-and-rust-for-zero-syscall-https-server.html It was on HN too: https://ne", "context": "", "use_case": "Web server I/O", "switched_from": "", "story": "Epoll vs. Io_uring in Linux"}, {"id": 777844560, "item_id": 48615285, "url": "https://news.ycombinator.com/item?id=48615285", "by": "Cloudef", "date": "2026-06-20", "stance": "recommend", "quote": "For large zero-copy buffers, io_uring is king however.", "excerpt": "Quite depends, I had times when my posix emulation of io_uring (with poll, not epoll) was faster than io_uring. For large zero-copy buffers, io_uring is king however. Also io_uring is useful even for non asynchronous IO as it can implement chain of operations as single atomic operation (mkdir + open it for example). For something like networking, if you are maximizing packets per second, you'll hit kernel limits[1] v", "context": "", "use_case": "async I/O for large buffers", "switched_from": "", "story": "Epoll vs. Io_uring in Linux"}, {"id": 769101696, "item_id": 48068856, "url": "https://news.ycombinator.com/item?id=48068856", "by": "otterley", "date": "2026-05-08", "stance": "warn", "quote": "Google disabled io_uring on its production servers", "excerpt": "At one point, Google disabled io_uring on its production servers (https://security.googleblog.com/2023/06/learnings-from-kctf-vrps-42-linux.html) - I don't know whether this is still true, though. Perhaps a Google can confirm.", "context": "", "use_case": "", "switched_from": "", "story": "You gave me a u32. I gave you root. (io_uring ZCRX freelist LPE)"}, {"id": 765156176, "item_id": 47822261, "url": "https://news.ycombinator.com/item?id=47822261", "by": "mananaysiempre", "date": "2026-04-18", "stance": "neutral", "quote": "io_uring, which does this kind of IPC with a kernel thread on the receiving side", "excerpt": "> eventfd always pays a syscall on both sides (~200-400ns) regardless of load. It\u2019s fairly standard to make the waiting side spin a bit after processing some data, and only issue another wait syscall if no more data arrives during the spin period. (For instance, io_uring, which does this kind of IPC with a kernel thread on the receiving side, literally lets you configure how long said kernel thread should spin[1].) [", "context": "", "use_case": "", "switched_from": "", "story": "Bypassing the kernel for 56ns cross-language IPC"}, {"id": 760475760, "item_id": 47529735, "url": "https://news.ycombinator.com/item?id=47529735", "by": "menaerus", "date": "2026-03-26", "stance": "recommend", "quote": "I would probably easily agree that io_uring in general is a better design", "excerpt": "> Also, it would be useful to test across different devices, since their behavior can vary significantly, especially when preconditioned or under corner-case workloads. Agreed. And from first-hand experience I know how painful this is, and how proving or disproving the hypothesis you have about certain wheel in the system can turn into a crazy rabbit hole, especially in the infrastructure software which due to ever i", "context": "", "use_case": "", "switched_from": "", "story": "io_uring, libaio performance across Linux kernels and an unexpected IOMMU trap"}, {"id": 756901264, "item_id": 47306329, "url": "https://news.ycombinator.com/item?id=47306329", "by": "ozgrakkurt", "date": "2026-03-09", "stance": "recommend", "quote": "https://docs.rs/io-uring/latest/io_uring/opcode/index.html", "excerpt": "https://docs.rs/io-uring/latest/io_uring/opcode/index.html You can click the source code link and read the code here. Macros aren\u2019t needed at all if every single operation isn\u2019t a different type.", "context": "", "use_case": "", "switched_from": "", "story": "A Grand Vision for Rust"}, {"id": 756252592, "item_id": 47265787, "url": "https://news.ycombinator.com/item?id=47265787", "by": "jfindley", "date": "2026-03-05", "stance": "warn", "quote": "the list of vulnerabilities in io_uring over the past 12 months[2] is pretty staggering to me.", "excerpt": "There are a couple of notable examples of projects[0] and companies[1] that have got tired of it, and no longer use it. There's considerable difficulty these days extrapolating \"real\" vulnerabilities from kernel CVEs, as the kernel team quite reasonably feel that basically any bug can be a vulnerability in the right situation, but the list of vulnerabilities in io_uring over the past 12 months[2] is pretty staggering", "context": "", "use_case": "", "switched_from": "", "story": "Fast-Servers"}, {"id": 755796976, "item_id": 47237311, "url": "https://news.ycombinator.com/item?id=47237311", "by": "jauntywundrkind", "date": "2026-03-03", "stance": "recommend", "quote": "Absolutely fricking sick!!", "excerpt": "> This patch is trying to make io_uring customizable via BPF, promising better waiting and polling patterns https://lore.kernel.org/bpf/cover.1763031077.git.asml.silence@gmail.com/ Absolutely fricking sick!! The write up of use cases here is so so wildly neat. Please please please, make the new completion queue engine in the kernel programmable with eBPF!!", "context": "", "use_case": "Linux async I/O", "switched_from": "", "story": "What's new in Linux kernel for PostgreSQL"}, {"id": 755632992, "item_id": 47227062, "url": "https://news.ycombinator.com/item?id=47227062", "by": "nickelpro", "date": "2026-03-02", "stance": "recommend", "quote": "io_uring wasn't built just for kicks", "excerpt": "mmap is slow because stalling on page faults is slow. Your process stalls and sits around doing nothing instead of processing data you've read already. You can google the benchmarks if you like. io_uring wasn't built just for kicks. https://www.bitflux.ai/blog/memory-is-slow-part2/", "context": "", "use_case": "", "switched_from": "", "story": "Why does C have the best file API"}, {"id": 748086720, "item_id": 46755420, "url": "https://news.ycombinator.com/item?id=46755420", "by": "king_geedorah", "date": "2026-01-25", "stance": "neutral", "quote": "io_uring supports submitting openat requests, which sounds like what you want", "excerpt": "io_uring supports submitting openat requests, which sounds like what you want. Open the dirfd, extract all the names via readdir and then submit openat SQEs all at once. Admittedly I have not used the io uring api myself so I can't speak to edge cases in doing so, but it's \"on the happy path\" as it were. https://man7.org/linux/man-pages/man3/io_uring_prep_open.3.html https://man7.org/linux/man-pages/man2/readdir.2.ht", "context": "", "use_case": "", "switched_from": "", "story": "I built a 2x faster lexer, then discovered I/O was the real bottleneck"}, {"id": 745082481, "item_id": 46567655, "url": "https://news.ycombinator.com/item?id=46567655", "by": "avsm", "date": "2026-01-10", "stance": "neutral", "quote": "The webserver I'm putting together also uses io_uring", "excerpt": "In a conventional GCed language, you need to minimise heap allocations to avoid putting too much pressure on the garbage collector. The OxCaml extensions allows values to be passed 'locally' (that is, on the callstack) as an alternative to heap allocation. When the function returns, the values are automatically deallocated (and the type system guarantees safety). This means that I can pass in a buffer, parse it, do m", "context": "", "use_case": "", "switched_from": "", "story": "Httpz \u2013 Zero-Allocation HTTP/1.1 Parser for OxCaml"}, {"id": 744390224, "item_id": 46524389, "url": "https://news.ycombinator.com/item?id=46524389", "by": "charcircuit", "date": "2026-01-07", "stance": "recommend", "quote": "which made it much safer", "excerpt": "It already did with the io_uring worker rewrite in 5.12 (2021) which made it much safer. https://github.com/axboe/liburing/discussions/1047", "context": "", "use_case": "", "switched_from": "", "story": "High-Performance DBMSs with io_uring: When and How to use it"}, {"id": 741922528, "item_id": 46370158, "url": "https://news.ycombinator.com/item?id=46370158", "by": "senderista", "date": "2025-12-23", "stance": "compare", "quote": "Windows registered network I/O (RIO) came before io_uring", "excerpt": "If that were true then presumably Microsoft wouldn't have ported it to Windows: https://learn.microsoft.com/en-us/windows/win32/api/ioringapi/ Although Windows registered network I/O (RIO) came before io_uring and for all I know might have been an inspiration: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh997032(v=ws.11)", "context": "", "use_case": "", "switched_from": "", "story": "Meta is using the Linux scheduler designed for Valve's Steam Deck on its servers"}, {"id": 741885216, "item_id": 46367826, "url": "https://news.ycombinator.com/item?id=46367826", "by": "asveikau", "date": "2025-12-23", "stance": "compare", "quote": "io_uring does more than IOCP.", "excerpt": "io_uring does more than IOCP. It's more like an asynchronous syscall interface that avoids the overhead of directly trapping into the kernel. This avoids some overheads IOCP cannot. I'm rusty on the details but the NT kernel has since introduced an imitation: https://learn.microsoft.com/en-us/windows/win32/api/ioringapi/", "context": "", "use_case": "", "switched_from": "", "story": "Meta is using the Linux scheduler designed for Valve's Steam Deck on its servers"}, {"id": 737218944, "item_id": 46076184, "url": "https://news.ycombinator.com/item?id=46076184", "by": "Xraider72", "date": "2025-11-27", "stance": "recommend", "quote": "io_uring became interesting to use for most use cases with zero copies", "excerpt": "In the real world, unless are writing a very specialized system, intended to run only on Linux 6.0 and never, it just is not realistic and you will need some sort of abstraction layer to support at the very least additionally poll to be portable across all POSIX and POSIX like systems. Then if you want your thing to also run on Windows, IOCP rides in too... I used 6.0 because 5.8-5.9 is roughly when io_uring became i", "context": "", "use_case": "Async I/O on Linux", "switched_from": "", "story": "A programmer-friendly I/O abstraction over io_uring and kqueue (2022)"}, {"id": 737210512, "item_id": 46075657, "url": "https://news.ycombinator.com/item?id=46075657", "by": "willtemperley", "date": "2025-11-27", "stance": "neutral", "quote": "Someone with a casual interest in Linux internals will probably get a poor impression of io_uring security", "excerpt": "Perhaps someone who knows what they're talking about should update the Wikipedia page on io_uring [1]. Someone with a casual interest in Linux internals will probably get a poor impression of io_uring security which appears to be largely due to Google using an old kernel in Android [2]. [1] https://en.wikipedia.org/wiki/Io_uring [2] https://github.com/axboe/liburing/discussions/1047", "context": "", "use_case": "", "switched_from": "", "story": "A programmer-friendly I/O abstraction over io_uring and kqueue (2022)"}]}