Skip to main content
This guide explains how Kubernetes uses resource requests and limits to schedule and enforce CPU and memory for workloads. It covers units, scheduler behavior, defaults and best practices, and how to enforce namespace-level constraints with LimitRange and ResourceQuota. We begin with a simple three-node cluster: each node advertises available CPU and memory capacity, and each pod consumes some of that capacity. For example, a pod that requests two CPUs and one unit of memory reduces the available resources on the node where the scheduler places it.
A schematic diagram of three server nodes (Node 01, Node 02, Node 03), each showing stacked CPU and memory (MEM) resource blocks. A small legend with colored gradient bars and a container icon appears above the nodes.
When scheduling a pod, the Kubernetes scheduler compares the pod’s resource requests against node capacity. If no node can satisfy the requests, the pod stays in Pending. Inspecting a pending pod with kubectl describe pod will show events such as “Insufficient cpu” or “Insufficient memory”.

Requests vs Limits — high-level

  • Request: the minimum amount of CPU or memory a container needs. The scheduler uses requests to place pods.
  • Limit: the maximum amount a container may use at runtime. The kubelet and kernel enforce limits.

Resource requests

A resource request is the guaranteed minimum the scheduler uses to reserve capacity for a container. For example, a container might request 1 CPU and 1Gi memory.
A slide titled "Resource Requests" on a dark blue background showing a small cube icon and two rounded cards labeled "CPU" (1) and "MEM" (1Gi).
Example: specify requests in a pod manifest (this container requests 2 CPUs and 4 Gi of memory):

CPU and memory units

CPU and memory support different unit formats; picking the right one prevents surprises.
  • CPU
    • Whole numbers (e.g., 1, 2) or millicores (e.g., 100m = 0.1 CPU).
    • Smallest unit is 1m.
    • One CPU typically maps to one AWS vCPU, one GCP core, one Azure core, or one hyperthread depending on the environment.
A dark presentation slide titled "Resource — CPU" with a blue CPU icon and a block labeled "CPU" showing the value 1. A bullet list to the right defines that 1 CPU equals 1 AWS vCPU, 1 GCP Core, 1 Azure Core, or 1 Hyperthread.
  • Memory
    • Supports binary suffixes (Ki, Mi, Gi) and decimal suffixes (K, M, G).
    • Gi is gibibyte (1024^3 bytes); G is gigabyte (1000^3 bytes).
    • Use binary units (Mi, Gi) for precise sizing when needed.
A presentation slide titled "Resource – Memory" with a stylized memory block labeled "MEM" and "1G." To the right are bullet points listing decimal and binary unit definitions (G, M, K and Gi, Mi, Ki) with their byte values.

Resource limits

If no limits are set, a container can consume up to the node’s available resources. Limits let you cap usage so workloads cannot exceed defined CPU or memory values. Example pod with both requests and limits — requests guarantee a minimum while limits cap the maximum:
An infographic titled "Resource Limits" showing two stacked columns of rounded blocks representing CPU (blue) and MEM (orange). A dashed line labels "1 vCPU" across the CPU column and a small container icon sits below.

CPU vs Memory behavior when exceeding limits

  • CPU: when a container exceeds its CPU limit, the kernel throttles CPU usage so it cannot run above the configured limit.
  • Memory: memory cannot be throttled. If a container uses more memory than its limit and the node cannot free memory, the kernel’s OOM killer may terminate the container. You will see OOMKilled in pod status or events when this happens.
A slide titled "Exceed Limits" shows stacked blocks for CPU and MEM with dashed lines marking 2 vCPU and 2 Gi thresholds. To the right are two buttons labeled "Terminate" and "Out of Memory (OOM)."
Memory limits are strict: if a container exceeds its memory limit and the system cannot reclaim memory, the container may be killed (OOMKilled). Always size memory conservatively and monitor OOM events.
Kubernetes does not automatically set requests or limits unless you configure objects such as LimitRange. Without requests, the scheduler cannot reserve resources and a single pod can monopolize node resources. Common scenarios and their implications:
An infographic titled "Behavior — CPU" showing four side-by-side scenarios of CPU and memory allocation under different combinations of requests and limits. Each column uses colored blocks in CPU and MEM grids to illustrate how vCPU allocation changes when requests and/or limits are set.
Tip: For CPU, it is common to set requests and leave limits unset to allow bursty workloads to use unallocated CPU. For memory, set both requests and limits when possible because memory overuse can trigger OOM kills.

LimitRanges — namespace defaults and constraints

Use a LimitRange to provide namespace-level defaults, minimums, and maximums for container requests and limits. LimitRanges only apply to pods created after the LimitRange is added or updated; they do not mutate existing pods. Example LimitRange for CPU:
Example LimitRange for memory:
LimitRanges are applied at the namespace level and affect only new pods created after the LimitRange is in place. They help enforce sensible defaults and prevent runaway resource usage.

ResourceQuota — cap total consumable resources per namespace

ResourceQuota enforces a hard limit on the aggregate resources a namespace can consume (requests, limits, object counts, etc.). This is useful for multi-tenant clusters or to prevent a namespace from exhausting cluster-wide resources. Example ResourceQuota limiting aggregate requests and limits:
This example caps the total requested CPU in the namespace to 4 CPUs and requested memory to 4 GiB, while allowing a higher ceiling for limits across all objects in that namespace.

Conclusion

Requests and limits make resource consumption predictable and protect cluster stability:
  • Use requests so the scheduler can place pods correctly.
  • Use limits to prevent runaway resource usage and protect node stability.
  • Use LimitRange to provide sensible defaults and bounds at the namespace level.
  • Use ResourceQuota to control the total resources a namespace may consume.
Try these manifests in a lab cluster to observe how requests, limits, LimitRanges, and ResourceQuotas interact in practice. Links and references

Watch Video