Blocking vs Non-Blocking I/O Lab (Interactive)
Route 100K sockets through thread-per-connection, select, poll, epoll, and io_uring models. Compare memory, syscalls, and per-event kernel scanning across the five classical I/O models as connection count and activity ratio change.
C10K: Blocking I/O vs epoll vs io_uring
Route 10,000 sockets through five classic I/O models and measure the kernel tax per event.
Kernel red-black tree + ready list: callbacks push only ACTIVE sockets; epoll_wait returns instantly.
200 of 10,000 sockets are ready this instant.
select()/poll() pay scanning only the 200-entry ready list per wakeup — that O(N) vs O(ready) gap is why Nginx, Envoy, Redis and Node.js all sit on epoll/kqueue.
io_uring removes the last ~2.4 μs of syscall transitions (epoll_wait + read) under Spectre-mitigated KPTI by sharing SQ/CQ rings in memory.
How It Works Under the Hood
The C10K problem exposed thread-per-connection’s fatal math: 10,000 idle sockets means 10,000 stacks and wakeup context switches. select() and poll() scan all O(N) descriptors per event — and select caps at 1,024 fds. epoll flips the model: NIC interrupts push ready sockets onto a kernel list, so cost scales with activity, not population. io_uring removes the remaining syscall transitions with shared submission/completion rings.
Core Architectural Principles
- Blocking model memory = connections x thread stack; multiplexed models pay per active socket only.
- select/poll cost grows with total fds; epoll returns only the ready list in O(active).
- io_uring’s SQ/CQ shared rings drive the syscall rate for I/O to zero.
For realtime server designs say: "one epoll/kqueue loop per core, edge-triggered, no thread-per-connection" and know why — O(1) ready-list dispatch. Then level up: mention io_uring for high-IOPS storage engines and warn that a single CPU-bound handler freezes every socket on the loop.
Multiplexing scales connections on tiny memory but forces state-machine-style code, while thread-per-connection stays simple and dies around 10K clients.