Skip to main content

Kubernetes

requests vs limits

Short answer

Requests are what the scheduler reserves for you. Limits are the ceiling the kernel enforces. For memory, hitting the limit is fatal; for CPU it only slows you down.

In simple terms

A request is a promise made at scheduling time: “this container needs at least this much, so only place it on a node that has it spare.” It shapes where the pod goes, and it is what the cluster subtracts from a node's available capacity.

A limit is a boundary enforced while the container runs. It says “whatever happens, do not use more than this.”

The part that surprises people is that the two resources behave completely differently at the boundary. CPU is compressible — exceed your share and you simply get scheduled less often. Memory is not. There is no way to give a process less memory than it just asked for, so the kernel's only option is to kill it.

What actually happens

Requests are consumed by the scheduler when it filters nodes, and they determine the pod's QoS class. All containers with equal requests and limits gives `Guaranteed`; some requests set gives `Burstable`; nothing set gives `BestEffort`, which is evicted first under node pressure.

A CPU limit is implemented as CFS quota — a cap on how much CPU time the cgroup receives per period. Exceeding it means throttling, which shows up as latency rather than as an error.

A memory limit is the cgroup memory ceiling. Exceeding it triggers the OOM killer against processes in that cgroup, and the container terminates with exit code 137. Nothing is throttled and nothing is negotiated; the process is killed without being given a chance to shut down.

A shape that works for most services

resources:
  requests:
    memory: "256Mi"   # near typical observed usage
    cpu: "100m"       # near typical observed usage
  limits:
    memory: "512Mi"   # above observed peak — this is the kill line
    # No CPU limit. See the note.

The omission is deliberate. A CPU limit throttles exactly when the container is busiest, which presents as latency nobody can explain rather than as throttling. Unless you need hard multi-tenant isolation, a CPU request alone allocates fairly and lets a service use spare capacity during a spike.

◑ The mistake this causes

Setting requests equal to peak usage, to be safe.

Why people do it It feels conservative. In practice requests are a reservation, so inflating them makes the cluster look full while nodes sit mostly idle — and you pay for the difference.

What you see Pods stuck in `Pending` with `0/5 nodes are available: Insufficient memory`, on a cluster whose actual memory utilisation is 30%. The scheduler is refusing to place pods against reservations, not against usage.

How it shows up in production

The opposite mistake is more dangerous. With no memory limit, a container with a slow leak grows until the node runs out, and then the kernel starts killing processes — possibly not yours. A memory problem in one workload becomes an outage in an unrelated one on the same node.

Both mistakes come from the same root: sizing from intuition rather than measurement. The numbers are available from `kubectl top pod --containers`, and they only mean anything if you sample across a full load cycle including start-up.

How to tell which one you are hitting

Pod stuck in Pending with an insufficient-resource message?
That is requests, not limits — the scheduler cannot find a node with enough unreserved capacity. Compare your requests against real usage before adding nodes.
Container terminated with exit code 137?
That is a memory limit being enforced. `kubectl describe pod` will show `Last State: Terminated, Reason: OOMKilled`.
Latency that rises under load with no errors?
Suspect CPU throttling. Check the `container_cpu_cfs_throttled_seconds_total` metric if you have it — throttling is invisible in application logs by design.
How this gets asked in an interview

Usually phrased as “What is the difference between a resource request and a limit?”

What a strong answer contains Scheduling versus enforcement, then the asymmetry between the two resources: CPU is compressible so a limit throttles, memory is not so a limit kills. Bringing up QoS classes and eviction order shows you have thought about what happens under node pressure.

The follow-up “Should you set a CPU limit?” is a genuinely open question, and having a reasoned position — either way — is worth more than repeating a default.

What comes next

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere