Crisp answer: Requests are what the scheduler uses to find a node with enough capacity. Limits are what the kernel enforces at runtime. The ratio between them determines the pod's QoS class, which controls eviction priority.
Requests:
resources:
requests:
cpu: "250m" # 0.25 CPU cores
memory: "128Mi" # 128 mebibytes
The scheduler sums up all pod requests on a node. If a node has 4 CPUs and all scheduled pods request 3.8 CPUs total, the remaining 0.2 CPUs is what the scheduler sees as "available." The scheduler will not place a pod requesting 0.5 CPUs on this node even if actual CPU usage is low. Requests are a scheduling constraint, not a runtime limit.
Limits:
resources:
limits:
cpu: "500m" # 0.5 CPU cores
memory: "256Mi" # 256 mebibytes
Limits are enforced by the kernel:
- CPU limit: Enforced by the Linux CFS scheduler via cgroup cpu.cfs_quota. A pod hitting its CPU limit is throttled — its processes are paused until the next quota period. The pod is NOT killed.
- Memory limit: Enforced by cgroup memory.max. A pod exceeding its memory limit triggers the kernel OOM killer. The process is killed immediately. This is the OOMKilled status in Kubernetes.
QoS classes:
Kubernetes assigns a QoS class based on requests and limits:
| Class | Condition | Eviction priority |
|---|---|---|
| Guaranteed | Every container has requests == limits for both CPU and memory | Last to be evicted |
| Burstable | At least one container has requests set, and requests != limits | Middle priority |
| BestEffort | No requests or limits set at all | First to be evicted |
kubectl describe pod <pod> | grep "QoS Class"
# QoS Class: Burstable
# See cgroup class for a pod:
cat /proc/<pid>/cgroup | grep kubepods
# /kubepods/burstable/pod<uid>/...
When to use each:
| Workload | Recommended | Why |
|---|---|---|
| Critical production service | Guaranteed | Never evicted, predictable performance |
| Normal application | Burstable | Can burst when resources available, some eviction risk |
| Background batch job | BestEffort | OK if it gets evicted, it will retry |
Common mistake — CPU throttling:
A pod can be consuming less CPU than its limit but still be throttled. This happens because Linux CFS quotas work in short periods (typically 100ms). A pod consuming 0.5 CPUs on average might burst to 2 CPUs for 50ms in a period, hit the quota, then get throttled for 50ms. This appears as high latency at the 99th percentile.
# Check CPU throttling metrics in Prometheus:
container_cpu_cfs_throttled_seconds_total
container_cpu_cfs_throttled_periods_total
# If throttling_ratio > 25%, the CPU limit is too low
What to say in the interview:
"Requests are what the scheduler uses — it finds a node with enough unallocated capacity. Limits are what the kernel enforces at runtime. CPU limits throttle the process via cgroup quotas, memory limits kill it via the OOM killer. QoS class comes from the ratio: if requests equal limits you're Guaranteed and last to be evicted; no requests at all is BestEffort and first. One subtle issue is CPU throttling — a pod can be under its average CPU limit but still get throttled in short periods, which shows up as latency spikes. You catch that in the container_cpu_cfs_throttled metrics in Prometheus."