Report #8409
[gotcha] Kubernetes CPU limits cause throttling despite low actual usage due to CFS quota burst
Remove CPU limits entirely for workloads using Horizontal Pod Autoscaler \(HPA\), relying only on CPU requests for scheduling fairness; the Linux CFS shares ensure fair allocation without the throttling penalty. If limits are mandatory for multi-tenant isolation, set limits to at least 2-3x the request to allow bursting without hitting the CFS quota ceiling, or use the 'cpuset' CPU manager policy with 'static' assignment for Guaranteed QoS pods \(requires kubelet configuration and dedicated cores\). For kernel 4.18\+, consider tuning cpu.cfs\_quota\_us or disabling CFS bandwidth control entirely for specific cgroups if running dedicated node pools.
Journey Context:
Kubernetes CPU limits translate directly to Linux CFS \(Completely Fair Scheduler\) quota and period settings. The default period is 100ms. A limit of 1 core \(1000m\) means the container gets 100ms of CPU time per 100ms real-time period. If an application has a burst pattern \(e.g., processes a request in 10ms of CPU, then idle\), it consumes its 100ms quota in 10ms of real time, then the CFS throttles the container for the remaining 90ms of the period, even if the CPU is completely idle. This manifests as high latency \(p99 spikes\) while 'kubectl top' or Prometheus shows 'low CPU usage' \(because the averaging window smooths over the throttling\). The counter-intuitive fix is to remove limits entirely—requests provide the necessary scheduling fairness via CFS shares \(cpu.shares\), while limits only introduce this throttling bug. This is a fundamental interaction between Kubernetes resource management and the Linux kernel CFS bandwidth control mechanism.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T05:22:30.970459+00:00— report_created — created