πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Configuration beginner ⏱ 15 minutes K8s 1.28+

Kubernetes Resource Requests and Limits Guide

Configure CPU and memory requests and limits in Kubernetes. Understand QoS classes, OOMKilled, CPU throttling, and right-sizing with VPA recommendations.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Configure CPU and memory requests and limits in Kubernetes. Understand QoS classes, OOMKilled, CPU throttling, and right-sizing with VPA recommendations.

The Problem

Pods get OOMKilled, throttled, or stuck Pending because requests and limits are missing, mismatched, or copy-pasted without matching the workload’s actual usage.

The Solution

Set Requests and Limits

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: app
      image: my-app:v1
      resources:
        requests:          # Minimum guaranteed
          cpu: 250m        # 0.25 CPU cores
          memory: 256Mi    # 256 MiB
        limits:            # Maximum allowed
          cpu: "1"         # 1 CPU core
          memory: 512Mi    # 512 MiB - OOMKilled if exceeded

CPU vs Memory Units

ResourceUnitsExamples
CPUMillicores (m)100m = 0.1 core, 1000m = 1 core, 1.5 = 1500m
MemoryBytes (Mi, Gi)128Mi, 1Gi, 512Mi

QoS Classes

ClassConditionEviction Priority
Guaranteedrequests == limits for all containersLast to evict
BurstableAt least one request set, requests < limitsMiddle
BestEffortNo requests or limits setFirst to evict
# Guaranteed QoS β€” best for production
resources:
  requests:
    cpu: 500m
    memory: 256Mi
  limits:
    cpu: 500m        # Same as request
    memory: 256Mi    # Same as request

What Happens When Limits Are Exceeded?

# CPU: Throttled (slowed down, not killed)
# Memory: OOMKilled (pod restarted)

# Check for OOM kills
kubectl describe pod <name> | grep -i oom
kubectl get pod <name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'
# Output: OOMKilled

Right-Sizing with VPA

# Install VPA, create VPA object in "Off" mode, then check recommendations
kubectl describe vpa my-app-vpa
# Target:     cpu: 120m, memory: 200Mi  ← use these as your requests
graph TD
    A[Pod resources] --> B{requests}
    B -->|Scheduler uses for placement| C[Node with enough capacity]
    A --> D{limits}
    D -->|CPU exceeded| E[Throttled - slowed down]
    D -->|Memory exceeded| F[OOMKilled - restarted]

Common Mistakes

# Memory limit below request β€” rejected by the API server, not just bad practice
resources:
  requests: {memory: "512Mi"}
  limits: {memory: "256Mi"}    # INVALID: must be >= request
# No limits at all β€” this container can consume the entire node's remaining capacity
resources:
  requests: {memory: "128Mi", cpu: "100m"}
  # limits omitted

Requests set far above actual usage waste cluster capacity just as much as missing limits risk instability β€” both show up in a kubectl top pods vs. requests comparison.

Namespace-Level Defaults and Caps

Don’t rely on every team remembering to set resources correctly β€” LimitRange fills in defaults and enforces bounds, ResourceQuota caps the namespace total:

apiVersion: v1
kind: LimitRange
metadata: {name: default-limits, namespace: production}
spec:
  limits:
    - type: Container
      default: {memory: "256Mi", cpu: "500m"}
      defaultRequest: {memory: "128Mi", cpu: "100m"}
      min: {memory: "64Mi", cpu: "50m"}
      max: {memory: "2Gi", cpu: "2"}
apiVersion: v1
kind: ResourceQuota
metadata: {name: compute-quota, namespace: production}
spec:
  hard: {requests.cpu: "10", requests.memory: "20Gi", limits.cpu: "20", limits.memory: "40Gi", pods: "50"}

Troubleshooting

# OOMKilled β€” check for the event, then raise the memory limit or fix the leak
kubectl describe pod myapp | grep -i oom
kubectl get events --field-selector reason=OOMKilled

# Pending β€” insufficient node capacity for the requested resources
kubectl describe pod myapp | grep -i insufficient

# CPU throttling β€” read the cgroup stats directly
kubectl exec myapp -- cat /sys/fs/cgroup/cpu.stat

Frequently Asked Questions

Should I always set limits?

Set memory limits always (prevents OOM from affecting other pods). CPU limits are debatable β€” throttling can cause latency spikes. Some teams set CPU requests only and skip CPU limits.

What are good defaults?

Start with requests based on actual usage (check kubectl top pods). Set memory limit = 2Γ— request. Adjust based on monitoring.

Best Practices

  • Always set memory limits β€” an unbounded container can starve every other pod on the node
  • CPU limits are debatable β€” throttling can cause latency spikes; some teams set CPU requests only
  • Use LimitRange for namespace defaults so a forgotten resource block doesn’t default to BestEffort
  • Right-size from real data β€” kubectl top pods or VPA recommendations, not guesses
  • Re-check after workload changes β€” a code change that alters memory/CPU profile makes old limits stale

Key Takeaways

  • Requests drive scheduling; limits are enforced at runtime β€” CPU throttles, memory OOMKills
  • Memory limit must be β‰₯ request or the pod spec is rejected outright
  • LimitRange sets namespace defaults/bounds; ResourceQuota caps the namespace total
  • QoS class (Guaranteed/Burstable/BestEffort) is derived automatically and determines eviction order
  • Diagnose OOMKilled with kubectl describe/events, Pending with insufficient-resource events, throttling via cgroup cpu.stat
#resources #requests #limits #cpu #memory #qos #kubernetes
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens