Kubernetes Resource Requests and Limits (2026): Set Them Right and Prevent OOMKilled & FailedScheduling
TL;DR Requests are what the scheduler spends; limits are what the kernel enforces. A pod is placed based on its requests, and killed or throttled based on its limits. CPU and memory fail differently: exceed your CPU limit and you get throttled (slow); exceed your memory limit and you get killed (OOMKilled, exit code 137). Two of the most common Kubernetes errors are born here: FailedScheduling…
Requests represent the minimum resources that a container is assured, while limits cap the maximum resources a container can consume. When creating a pod, the scheduler uses requests to determine where it can fit within the node's available capacity, and the kernel enforces limits via cgroups to prevent runaway resource usage.
In the context of CPU, containers can request a portion of a core or specify a specific value like 500m (0.5 core). The kernel can throttle a container if it exceeds its request but is not fully utilized. Memory, on the other hand, is incompressible and cannot be slowed down by the kernel, so exceeding a memory limit results in immediate OOMKilled, indicated by an exit code of 137.
A common mistake is to guess resource numbers without measuring actual usage. This often leads to pods stuck in a Pending state due to FailedScheduling, where requests exceed the node's capacity, or containers dying with OOMKilled because limits were set arbitrarily. Measuring resource usage over a full traffic cycle and setting requests near typical peak values, while giving memory a limit with appropriate headroom, helps avoid these pitfalls.
The scheduler is primarily concerned with requests, placing new pods only where their requests can be accommodated. However, the kernel strictly enforces limits. CPU is compressible – the kernel can delay a container, while memory is incompressible, meaning the kernel must kill the process when it exceeds its limit. This fundamental difference makes memory limits particularly critical.
When setting memory requests and limits, it's essential to base them on measured peak usage plus a safety margin for unexpected spikes. A limit set at the average usage level will only trigger OOMKilled during the busiest periods. Additionally, some runtimes, like JVMs, may configure their own heap size independently of cgroup limits, leading to unexpected OOMKilled events. Therefore, it's crucial to ensure that runtimes respect the container's memory constraints to avoid surprises.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.