TL;DR: Requests drive scheduling and CPU weight under contention; limits cap runtime consumption. CPU quota can throttle, while failed memory reclaim at the cgroup limit can trigger OOM killing. For memory-pressure eviction, the kubelet ranks whether usage exceeds requests, then priority and relative excess. QoS is not a strict three-class eviction queue.
How to approach it
Separate the two audiences in the first sentence, because that framing makes everything else obvious. Then handle CPU and memory separately, since treating them the same is the main error.
A strong answer
Requests are a scheduling contract. The scheduler sums requests on each node and places your pod where the sum still fits allocatable capacity. Requests are not hard upper bounds, so a pod can use more if the node has room. CPU requests also influence cgroup shares/weight during contention. This is why a node can show 30 percent CPU usage and still refuse to schedule anything.
Limits are enforced by the kernel through cgroups, and the two resources behave differently.
CPU is compressible. A limit becomes a CFS quota: with a configured 100ms quota period, a limit of 1000m allows 100ms of aggregate CPU time per period. Exceed it and the process is not killed, it is frozen until the next period. This is why CPU limits cause latency spikes rather than failures, and why a multi-threaded runtime can burn its whole quota in a few milliseconds and then sit idle for the rest of the period. Diagnosed by comparing nr_throttled to nr_periods in the container's cpu.stat.
Memory is incompressible. The kernel can reclaim caches and other reclaimable memory. If an allocation cannot succeed within memory.max after reclaim, the cgroup can enter OOM handling and kill a process. Confirm OOMKilled and kernel/cgroup evidence; exit 137 alone only indicates a SIGKILL-derived exit status.
For ordinary container-level CPU and memory resources, QoS classification is:
| Class | Condition | Eviction interpretation |
|---|---|---|
| Guaranteed | CPU and memory requests equal their limits for every container | usually within requests, but not immune |
| Burstable | some CPU/memory request or limit, but not Guaranteed | rank depends on usage and priority |
| BestEffort | no CPU/memory requests or limits | nonzero usage exceeds zero request |
For memory pressure, over-request pods rank before those within requests, then priority and relative excess decide ordering. Disk-pressure eviction uses disk-related usage and requests; QoS does not encode ephemeral storage. Node-pressure eviction.
The opinionated part, and it is a live debate worth having in the interview: set memory limits, and think hard before setting CPU limits. Memory limits protect the node from one pod taking it down. CPU limits enforce an upper bound; requests influence contention weights but do not cap consumption, and they introduce throttling that hurts latency. Setting requests accurately and omitting CPU limits is a defensible position at many shops. Where you do need them is multi-tenant clusters where a noisy neighbour is a real risk.
Resource exercise: an idle node rejects another pod
A fictional node has 8 CPUs allocatable. Four existing pods each request 2 CPUs but currently use only 0.3. The node shows 1.2 CPUs of observed use, yet its requests already total 8. A new 1-CPU request cannot fit under that scheduling constraint. Lower requests only after measuring representative contention and burst needs; idle observations alone do not establish a safe setting.
For a separate container with a one-CPU quota and a 100-ms period, four runnable threads can collectively spend 100 ms of CPU in about 25 ms of wall time if enough cores are available. They may then be throttled for the remainder. Correlate throttled periods with request latency and workload before changing the limit; the precise accounting depends on configured cgroup settings.
Memory investigation is different. Distinguish an OOM within the container's cgroup from kubelet node-pressure eviction and a node-level OOM. Preserve termination reasons and kernel evidence. Increasing a memory limit can remove one failure while exposing the node to greater pressure, so check node headroom and neighbour impact as well.
What interviewers probe next
"Why did raising the CPU limit fix a latency problem?" Reduced throttling is one explanation. Compare quota counters, CPU demand and latency before and after; the improvement alone does not uniquely establish the cause.
"What is the node's allocatable versus capacity?" Capacity minus kube-reserved, system-reserved and eviction thresholds. Scheduling works against allocatable, which is why a 16-core node does not offer 16 cores.
"What does a LimitRange do?" Applies defaults per namespace so nothing ships as BestEffort by accident, which is the practical fix for the eviction-order problem at scale.
Common mistakes
Treating CPU and memory as symmetric. Throttled and killed are very different outcomes.
Setting limits equal to requests everywhere for "Guaranteed" without noticing you have also capped every burst.
Sizing requests from peak usage, which reserves capacity permanently for a spike that happens twice a day.