epoll
Linux's scalable I/O event notification facility (2.5.44+) that lets one thread watch many file descriptors, superseding select/poll for most network servers before io_uring.
epoll is Linux’s scalable I/O event notification mechanism, introduced in kernel 2.5.44 and considered the standard for high-connection-count servers from the mid-2000s until io_uring’s rise. Unlike select and poll, which scan the entire descriptor set on every call, epoll maintains kernel-side interest and readiness lists, so the cost of a wait is proportional to the number of ready descriptors, not watched ones.
Mechanically, it exposes three syscalls: epoll_create1 creates the epoll instance, epoll_ctl adds/removes/modifies watched descriptors, and epoll_wait blocks until one or more are ready. Readiness can be level-triggered (default; fires as long as the fd is ready) or edge-triggered (fires only on state transitions, requiring non-blocking fds and drain-to-EAGAIN discipline).
For the low-latency crowd, epoll’s cost floor is the per-epoll_wait syscall plus the per-operation recv/send syscalls. That floor is what io_uring’s shared-ring design eliminates. Nonetheless, epoll remains the right default for workloads where batch sizes stay small, kernel versions lag, or portability to older Linux matters.
Common misconception: epoll is not “always slower” than io_uring. For single-shot, latency-sensitive ping-pong workloads at low queue depth, a well-tuned epoll server can match or beat a naive io_uring one.