Free — no signup required

Setting the Right Values: A Practical Framework

2 min read

How to Actually Choose Numbers

The hardest part of resource tuning is not understanding the concepts — it's knowing what numbers to put in the YAML. Here is a repeatable process.

Step 1: Measure, Don't Guess

Deploy your application with no Limits and generous Requests. Let it run under realistic load (load test or real traffic). Observe actual consumption — real-time per-Pod usage, or historical peak usage over a window like 24 hours if Prometheus is available.

Step 2: Set Requests at the P95 Steady-State Usage

Your Request should reflect what the application uses under normal load — not peak, not idle. The P95 (95th percentile) of observed memory and CPU usage is a good baseline. This ensures the Scheduler places the Pod on a Node that can genuinely support it.

Step 3: Set Memory Limits at 1.5–2x the Request

This gives headroom for traffic spikes and GC pauses (especially important for JVM-based applications) without allowing unbounded growth. If your P95 memory is 300Mi, set limits.memory: "512Mi".

Step 4: Be Cautious with CPU Limits

For latency-sensitive services, consider omitting CPU Limits entirely and relying only on CPU Requests. If you must set CPU Limits (e.g., for multi-tenant clusters where noisy neighbors are a concern), set them at 2–4x the Request to minimize throttling under burst conditions.

Step 5: Use VPA Recommendations as a Sanity Check

Even if you don't run VPA in Auto mode, you can run it in Off mode to get automated recommendations. Its Recommendation section shows Lower Bound, Target, and Upper Bound values based on observed usage — use these as a cross-check against your manual estimates.

The LimitRange Safety Net

For any namespace where developers deploy workloads, set a LimitRange to enforce defaults and prevent BestEffort Pods from being created accidentally. It declares default requests and limits applied to any container that omits resources, plus a maximum ceiling — for example, defaulting to 100m/128Mi requested and 500m/256Mi limited, while capping any container at 2 CPU cores and 2Gi of memory even with an explicit override.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free