The Paradox of High Traffic
There is a counterintuitive problem with interrupt-driven I/O: at very high packet rates, interrupts become the bottleneck. If a 10 Gbps NIC fires an interrupt for every single packet, the CPU spends more time handling interrupts than processing packets. The solution is to stop using interrupts when traffic is heavy — and switch to polling.
NAPI (New API) is the Linux networking subsystem's answer to this paradox. It was introduced in Linux 2.6 and is now the standard for all high-performance NIC drivers.
NAPI works as follows:
- First packet arrives: The NIC fires a hardware interrupt (Top Half). The driver acknowledges it and disables further interrupts from this NIC.
- The driver schedules a poll: It adds itself to a poll list and triggers a SoftIRQ.
- The SoftIRQ runs: Instead of processing one packet, it calls the driver's
poll()function, which drains the NIC's receive ring buffer — processing up tobudgetpackets (default: 64) in a tight loop. - If the ring is empty: Interrupts are re-enabled. The system returns to interrupt-driven mode.
- If the ring is still full: The poll is rescheduled. Interrupts remain disabled.
The result: under light load, you get the low latency of interrupt-driven I/O. Under heavy load, you get the high throughput of polling — without the CPU burning cycles asking "anything new?" when there is nothing to process.
Interrupt coalescing is a hardware-level complement to NAPI's software polling. Instead of firing one interrupt per packet, the NIC is configured to hold off — accumulating several packets, or waiting a small tunable delay (commonly tens of microseconds), before raising a single interrupt for the whole batch. NIC configuration tools expose this delay (often called rx-usecs) along with whether a given driver reports NAPI support in the first place. The trade-off is the same as NAPI's own: a longer coalescing window means fewer interrupts but slightly higher per-packet latency.
Trade-off: Interrupt coalescing and NAPI polling add latency (up to the coalescing delay) in exchange for throughput. For latency-sensitive workloads (HFT, real-time gaming servers), you may want to reduce or disable coalescing — at the cost of higher CPU utilization.