2026-09-03
HN Discussion: 1 points, 1 comments
There's a comfortable mental model that most systems programmers carry around: when a process dies, the kernel cleans up after it. File descriptors close, memory unmaps, pending syscalls unwind. It's one of the load-bearing assumptions behind supervisors, crash-only software, and every "just kill -9 it" ops runbook ever written.
This post from the YDB team pokes a rather alarming hole in that assumption. With io_uring, in-flight I/O operations submitted to the kernel's shared ring buffer can outlive the process that submitted them — even after the process has been reaped and its PID is gone. The kernel worker threads servicing those operations don't know or care that userspace has departed; they continue writing to buffers, touching files, and completing operations that belong to a ghost.
Why this matters for anyone building storage engines, databases, or high-throughput I/O layers:
YDB is a distributed SQL database, so this isn't academic hand-wringing — they hit these issues while trying to use io_uring for its promised throughput wins over epoll and threaded I/O. The post is worth reading because it's a concrete case study of how a "faster syscall interface" is actually a fundamentally different lifetime model glued onto a POSIX process abstraction that wasn't designed for it.
As io_uring adoption grows in databases (ScyllaDB, TigerBeetle, Ceph experiments) and language runtimes (Rust's tokio, Node's libuv exploration), these subtleties will bite more people. Better to read the postmortem than write your own.
