How to Set Resource Requests and Limits Properly
Master Kubernetes resource management with proper CPU and memory requests and limits. Avoid OOMKills, throttling, and resource contention.
The Problem
Your pods are being OOMKilled, CPU throttled, or scheduled to nodes without enough resources, causing performance issues.
The Solution
Configure appropriate resource requests (guaranteed minimums) and limits (maximum allowed) for your containers.
Understanding Requests vs Limits
| Type | Purpose | Behavior |
|---|---|---|
| Request | Minimum guaranteed resources | Used for scheduling decisions |
| Limit | Maximum allowed resources | Enforced at runtime |
Basic Configuration
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: myapp:latest
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"CPU Resources
CPU is measured in millicores (m):
1000m= 1 CPU core100m= 0.1 CPU core (10%)500m= 0.5 CPU core (50%)
CPU Behavior
- Request: Scheduler ensures node has this much CPU available
- Limit: Container is throttled if it exceeds this
resources:
requests:
cpu: "250m" # 25% of a core guaranteed
limits:
cpu: "1" # Can burst up to 1 full coreMemory Resources
Memory is measured in bytes:
128Mi= 128 Mebibytes1Gi= 1 Gibibyte256M= 256 Megabytes (decimal)
Memory Behavior
- Request: Scheduler ensures node has this much memory
- Limit: Container is OOMKilled if it exceeds this
resources:
requests:
memory: "256Mi" # 256 MiB guaranteed
limits:
memory: "512Mi" # OOMKilled if exceeds 512 MiBQuality of Service (QoS) Classes
Kubernetes assigns QoS classes based on resource configuration:
Guaranteed
Requests = Limits for all containers:
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: "500m"- Highest priority
- Last to be evicted
- Best for critical workloads
Burstable
Requests < Limits:
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"- Medium priority
- Evicted after BestEffort pods
- Good for typical applications
BestEffort
No requests or limits set:
resources: {}- Lowest priority
- First to be evicted
- Avoid in production
Guidelines for Setting Values
Starting Point
# Conservative starting values
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"Web Applications
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "1"Background Workers
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "2"Java Applications
Java needs more memory for JVM heap:
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2"Finding the Right Values
1. Observe Current Usage
# View resource usage
kubectl top pods
kubectl top nodes
# Get detailed metrics
kubectl describe pod myapp | grep -A5 "Limits:"2. Use Metrics Server
# Install metrics server if not present
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml3. Use Vertical Pod Autoscaler
VPA provides recommendations:
kubectl describe vpa myapp-vpaNamespace-Level Controls
LimitRange
Set defaults and constraints:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- default:
memory: "256Mi"
cpu: "500m"
defaultRequest:
memory: "128Mi"
cpu: "100m"
max:
memory: "2Gi"
cpu: "2"
min:
memory: "64Mi"
cpu: "50m"
type: ContainerResourceQuota
Limit total namespace resources:
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"Common Mistakes
1. No Limits Set
# BAD - can consume all node resources
resources:
requests:
memory: "128Mi"
cpu: "100m"
# No limits!2. Limits Too Low
# BAD - will cause OOMKill
resources:
limits:
memory: "64Mi" # Too small for most apps3. Requests Too High
# BAD - wastes resources
resources:
requests:
memory: "4Gi" # Way more than needed
cpu: "2"4. Memory Limit < Request
# INVALID - will be rejected
resources:
requests:
memory: "512Mi"
limits:
memory: "256Mi" # Must be >= requestTroubleshooting
Pod OOMKilled
kubectl describe pod myapp | grep -i oom
kubectl get events --field-selector reason=OOMKilledSolution: Increase memory limit.
Pod Pending (Insufficient Resources)
kubectl describe pod myapp | grep -i insufficientSolution: Reduce requests or add nodes.
CPU Throttling
Check if container is being throttled:
kubectl exec myapp -- cat /sys/fs/cgroup/cpu/cpu.statSolution: Increase CPU limit or remove it.
Best Practices
- Always set requests for production workloads
- Set memory limits to prevent runaway consumption
- CPU limits are optional - consider removing if causing issues
- Use VPA to find optimal values
- Monitor and adjust based on actual usage
- Start conservative and increase as needed
Key Takeaways
- Requests guarantee resources for scheduling
- Limits cap maximum resource usage
- Memory exceeding limit = OOMKill
- CPU exceeding limit = throttling
- Use QoS Guaranteed for critical workloads
- Monitor actual usage to right-size resources
π Go Further with Kubernetes Recipes
Love this recipe? Thereβs so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.
Inside the book, youβll master:
- β Production-ready deployment strategies
- β Advanced networking and security patterns
- β Observability, monitoring, and troubleshooting
- β Real-world best practices from industry experts
βThe practical, recipe-based approach made complex Kubernetes concepts finally click for me.β
π Get Your Copy Now β Start building production-grade Kubernetes skills today!
π Get All 100+ Recipes in One Book
Stop searching β get every production-ready pattern with detailed explanations, best practices, and copy-paste YAML.
Want More Kubernetes Recipes?
This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.