Two numbers, two very different jobs
Requests and limits look like a similar pair of numbers in a YAML file, but they do fundamentally different things. A request is what the Kubernetes scheduler reserves when deciding which node to place your pod on — it's a promise of guaranteed capacity. A limit is a hard ceiling the container is not allowed to exceed. Confusing the two, or setting both to the same rough guess, is one of the most common sources of production incidents in Kubernetes clusters.
What happens when CPU limits are too tight
Kubernetes enforces CPU limits using the kernel's CFS bandwidth controller, which works in fixed time windows (typically 100ms). If your container's CPU limit is set too close to its normal usage, any burst of activity — a garbage collection pause, a traffic spike, a cache miss cascade — gets throttled mid-window, even if the node has plenty of spare CPU sitting idle. The container doesn't crash; it just gets slower, which shows up as latency spikes that are maddening to diagnose because CPU usage graphs might not even look that high on average.
What happens when memory limits are too tight
Memory doesn't have a throttling mechanism the way CPU does. When a container exceeds its memory limit, the kernel's OOM killer terminates it immediately — no grace period, no warning signal the application can catch cleanly in every case. This is why memory limits deserve more headroom above observed peak than CPU limits typically need: a CPU limit that's occasionally hit costs you latency, but a memory limit that's occasionally hit costs you a killed pod and a restart.
What happens when limits are too loose
The opposite mistake is less dramatic but still costly. If every pod requests far more CPU and memory than it actually needs "just to be safe," the scheduler reserves that padding on every node, and clusters fill up with unused reserved capacity long before they're actually out of resources. This directly translates to real infrastructure cost — you're paying for nodes to sit mostly idle because the scheduler thinks they're full.
A sane starting formula
A reasonable default, absent workload-specific tuning, is to set requests near your observed average usage (so the scheduler's bin-packing reflects reality) and limits with meaningful headroom above your observed peak — commonly around 25-30% above peak, though the exact ratio depends on how bursty the workload is and how costly a throttle or restart would be for that specific service. Latency-sensitive services generally deserve more headroom; batch or background jobs can often run tighter.
Where the numbers should come from
None of this works without real usage data. Guessing requests and limits from a service's code alone, without looking at its actual CPU and memory behavior under production-like load, tends to produce numbers that are wrong in one direction or the other. Pull average and peak usage from your metrics stack over a representative window — ideally including at least one traffic peak, like a deploy, a cron job run, or a busy period — before setting these values, and revisit them periodically as the workload's behavior changes.
From numbers to YAML
Once you have sensible request and limit values, translating them into the resources block that actually goes in your Deployment or Pod spec is mechanical — but it's still easy to typo a unit (mixing up Mi and Gi is a classic mistake) or forget a quote. Generating the YAML directly from your calculated values, rather than typing it by hand, removes that last source of avoidable error.
Frequently Asked Questions
Requests are set near your observed average usage, since that's what the Kubernetes scheduler reserves and bin-packs against. Limits are set with headroom above your observed peak usage (roughly +30% for CPU, +25% for memory) so normal spikes don't trigger throttling or an OOMKill.
Yes — Kubernetes Resource Limit Calculator takes your observed CPU and memory usage and outputs suggested requests/limits plus ready-to-paste YAML. It's a one-time $5.49 purchase — no subscription, no account required.
CPU limits are enforced by throttling, which slows a container down but doesn't kill it. Memory limits are enforced by the OOM killer, which terminates the container immediately with no grace period — so memory limits generally deserve more conservative headroom above peak usage.
Yes — you can enter average and peak memory in either Mi or Gi, and the tool converts and formats the suggested values sensibly in the output.
Yes — the tool generates a complete resources: block with requests and limits formatted exactly as Kubernetes expects, ready to paste into your Pod or Deployment spec.