The Tickless Kernel and NO_HZ_FULL: Why Stopping the Timer Interrupt Made Servers Faster

2026-06-28

For decades, Linux ran a periodic timer interrupt — the "tick" — at 100, 250, or 1000 Hz on every CPU. Each tick the kernel updated jiffies, charged CPU time to the running task, checked for scheduling decisions, expired timers, and ran RCU callbacks. On an idle core, this meant waking up 1000 times a second to do almost nothing. On a busy core running one pinned thread, it meant 1000 unwanted context switches per second into kernel mode.

The tickless kernel (NO_HZ) fixed this in stages:

The catch with NO_HZ_FULL: it isn't free, and it isn't automatic. You boot with nohz_full=2-15 isolcpus=2-15 rcu_nocbs=2-15, dedicate CPU 0–1 as housekeeping cores, pin one userspace thread per isolated CPU, and ensure nothing else schedules there. Add a second runnable task and the tick comes right back.

Real-world example: high-frequency trading and DPDK packet-processing rigs. A market-data handler pinned to an isolated NO_HZ_FULL core can run a tight poll loop on a NIC ring buffer for seconds without a single kernel entry. Without it, every millisecond the timer interrupt would evict ~32 KB of L1-D, blow away branch predictor state, and add 3–8 µs of jitter — catastrophic when your tail-latency SLO is 10 µs. Cloudflare's published packet-processing measurements showed p99.99 latency dropping from ~80 µs to ~12 µs after enabling NO_HZ_FULL with proper isolation.

Rule of thumb: at HZ=1000, a tick costs roughly 1–3 µs of direct work plus another 2–5 µs of cache pollution. That's ~0.5% CPU overhead you can't see in top — and 100% of your jitter budget if you care about microsecond tails.

Check whether a core is actually tickless: cat /proc/interrupts | grep LOC and watch the per-CPU local timer interrupt count. On an isolated NO_HZ_FULL core running one busy thread, that counter should increment maybe once per second (for vmstat updates), not 1000 times.

Key Takeaway: NO_HZ_FULL eliminates the periodic timer interrupt on cores running exactly one task, trading configuration complexity for the microsecond-scale jitter elimination that latency-critical workloads require.

All newsletters