WSS
On this page
Containers & OrchestrationRequiredUpdated

Resource requests and limits

Defining minimum guaranteed resources and maximum caps to prevent noisy neighbor problems and node starvation.

What it is

In container orchestration, resource requests and limits define how much CPU and memory a container is allowed to use.

  • Requests: The guaranteed minimum amount of resources a container needs to function. The orchestrator uses this value exclusively for scheduling decisions. If a container requests 2 CPUs, the orchestrator will only place it on a node that has at least 2 unallocated CPUs available.
  • Limits: The hard maximum cap on resources a container can consume. If a container attempts to use more memory than its limit, the operating system’s Out Of Memory (OOM) killer will terminate it immediately. If it attempts to use more CPU than its limit, the system throttles its execution speed.

Why it matters

Without requests and limits, containers run in a “best effort” tier. They have unrestricted access to the underlying physical node’s resources.

If a memory leak occurs in a background worker container, it will silently consume all available RAM on the host. This starves the operating system, the orchestration daemons (like the kubelet), and every other application container running on that node. This is known as the “noisy neighbor” problem. Defining strict requests and limits isolates applications from one another, ensuring that a critical failure in one container cannot cascade and crash the entire physical machine.

How to implement

Resource constraints are defined in the Pod specification, mapped directly to Linux control groups (cgroups) by the container runtime. CPU is measured in cores (or millicores, where 1000m equals 1 full core). Memory is measured in bytes (typically using mebibytes Mi or gibibytes Gi).

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: my-app:1.4
    resources:
      requests:
        memory: "256Mi"
        cpu: "200m" # 0.2 of a core
      limits:
        memory: "512Mi"
        cpu: "500m" # 0.5 of a core

In this configuration, the orchestrator guarantees the container will receive at least 256 MiB of RAM and 0.2 CPU cores. It is physically prevented from using more than 512 MiB of RAM or 0.5 CPU cores.

Common mistakes

CPU Limits Causing Unnecessary Throttling

Unlike memory, CPU is a compressible resource. If a container exceeds its CPU limit, it is not killed; it is throttled. If a node has idle CPU cycles available, a container with a strict CPU limit is artificially prevented from using those free cycles. This severely degrades response times for bursty web traffic. Many modern performance guidelines recommend setting CPU requests accurately, but omitting CPU limits entirely to allow applications to utilize idle node capacity.

Setting Requests Equal to Limits for Everything

Setting requests exactly equal to limits (the “Guaranteed” QoS class in Kubernetes) is excellent for predictable databases, but terrible for cluster efficiency. It prevents overcommit. If every web server requests 2GB of RAM but only uses 500MB on average, you are wasting 75% of your cluster capacity. Setting requests lower than limits allows the orchestrator to pack more containers onto a node, relying on the statistical unlikelihood that every container will burst to its maximum limit simultaneously.

Ignoring Application Runtimes

Many legacy runtimes (especially older JVMs and Node.js versions) do not natively understand cgroup limits. A Java application might query the physical machine, see 32GB of RAM, and allocate a 16GB heap. However, if the container has a 4GB memory limit, the Linux kernel will instantly OOM kill the container the moment the JVM attempts to use its heap. Runtimes must be explicitly configured to respect container boundaries (e.g., -XX:+UseContainerSupport for Java).

Verification

To verify memory limits, look for OOMKilled statuses in the orchestrator.

kubectl get pods

If a Pod is OOMKilled, it means the application attempted to allocate more memory than the defined limit. You must either fix the memory leak in the code or raise the memory limit in the manifest.

To verify CPU throttling, query the underlying container metrics (usually via Prometheus or cAdvisor). Look for the container_cpu_cfs_throttled_seconds_total metric. If this number is rapidly increasing, the container is frequently hitting its CPU limit and being artificially slowed down by the kernel, degrading user experience.

Related topics

Sources & further reading