Kubernetes Resource Requests and Limits for JVM Apps
Fast recall
Quick revision
Core answer
requests to steady-state usage and limits to a safe ceiling (~1.5x heap). Use -XX:MaxRAMPercentage=75.0 with -XX:+UseContainerSupport so heap tracks the cgroup limit automatically. CPU: set requests to typical usage; be cautious with CPU limits — they cause CFS throttling that freezes all JVM threads including GC. For latency-critical services, use Guaranteed QoS (requests == limits) on memory; often leave CPU limits unset for Burstable flexibility.Whether you understand how Kubernetes resource management interacts with JVM memory, threads, and GC
Setting memory limit = `-Xmx` (ignoring metaspace, thread stacks, code cache) causing deterministic OOMKills; or setting aggressive CPU limits that throttle GC and inflate P99
Explain QoS classes (Guaranteed, Burstable, BestEffort), CFS throttling effect on GC pauses, Vertical Pod Autoscaler in recommend mode, and why `-Xmx` + `-Xms` equal avoids runtime heap resize pauses
Interview-ready guide
Interview answer
Kubernetes resource requests and limits are the two numbers the scheduler and kubelet use to decide where to place Pods and when to kill them. Getting them wrong for a JVM is one of the most common causes of OOMKilled pods and degraded cluster scheduling.
Requests — scheduling guarantees
resources.requeststells the scheduler how much CPU and memory the pod needs — the scheduler places the pod on a node that has at least this much available; if no node has enough, the pod stays Pending.- Requests define the Pod's QoS class: requests == limits gives Guaranteed (last to evict); requests < limits gives Burstable; no requests at all gives BestEffort (first to evict).
- Set memory requests based on actual idle JVM footprint from
kubectl top podduring normal operation; setting requests too low packs too many JVMs onto one node and they all OOMKill together when traffic hits.
Limits — enforcement ceilings
resources.limits.memoryis a hard ceiling enforced by cgroups — exceed and the kernel OOMKills; no warning, no JVM cleanup.- Set memory limits to at least 1.3–1.5x the heap (
-XX:MaxRAMPercentage) to account for metaspace, thread stacks, direct buffers — a JVM with 512MB heap needs at least 700–800MB total container limit. - CPU limits throttle using cgroup CPU quota — a JVM hitting the limit slows down but is not killed; excessive throttling (visible in
container_cpu_throttled_seconds_total) degrades GC performance because GC threads are also throttled.
Recommended settings
- Set
requests.memory == limits.memoryfor Guaranteed QoS — JVMs have unpredictable memory footprints and should not compete with other pods; predictable allocation is worth the lost burst capacity. - Leave CPU limits unset or set generously — CPU throttling degrades latency under load without meaningful protection; use CPU requests for scheduling placement without CPU limits for execution.
- For latency-critical services, set
-Xmxand-Xmsequal via matching RAMPercentage flags — this avoids full-GC pauses that happen when the heap resizes at runtime.
Observability
- Alert on
container_memory_working_set_bytes / limit > 0.85 for 10 minutesas an OOMKill early warning. - Alert on CFS throttled ratio > 5% for 15 minutes to catch CPU-throttling-induced latency before it shows up in the user experience.
- Use Vertical Pod Autoscaler in
recommendmode to discover correct sizing empirically over days — review suggestions before enabling automatic resizing.
Kubernetes Resource Requests and Limits for JVM Apps
Direct Answer
Memory: set requests to steady-state usage and limits to a safe ceiling (~1.5x heap). Use -XX:MaxRAMPercentage=75.0 with -XX:+UseContainerSupport so heap tracks the cgroup limit automatically. CPU: set requests to typical usage; be cautious with CPU limits — they cause CFS throttling that freezes all JVM threads including GC. For latency-critical services, use Guaranteed QoS (requests == limits) on memory; often leave CPU limits unset for Burstable flexibility.
Common Mistakes & Pitfalls
Setting memory limit = -Xmx (ignoring metaspace, thread stacks, code cache) causing deterministic OOMKills; or setting aggressive CPU limits that throttle GC and inflate P99
Check your understanding
Answer these without looking back at the article.
- What is the Vertical Pod Autoscaler and when would you use it?
- How do you diagnose that a pod is being CPU throttled vs OOMKilled?
- What happens to a BestEffort pod when node memory pressure occurs?
- Why should `-Xmx` and `-Xms` be equal for latency-critical services?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.