← Kubernetes memory limit calculator

How the Kubernetes calculator works

This page walks through how the Kubernetes calculator turns your usage data into resources.requests.memory and resources.limits.memory. The request and limit start from the shared sizing model; this page covers what happens after that. Statements backed by the documentation end with a Kubernetes docs link to the page that says so. Choices the documentation doesn't make for us are explained and marked Assumption, which links to the table of all of them.

01 What the two settings do

  • The request is what the scheduler uses to choose a node, and a container may use more than it when the node has memory to spare. Kubernetes docs
  • The limit is enforced by the kernel: a container that goes over it may be OOM-killed. Kubernetes docs
  • When a node runs short of memory, the kubelet evicts Pods, and only Pods using more than their requests are candidates. BestEffort Pods go first, then Burstable, then Guaranteed. Kubernetes docs

The calculator writes both settings for one container, in Mi (mebibytes), one of the suffixes the documentation lists for memory. Values are rounded up to a whole Mi.

02 Burstable: request and limit

request = average × (1 + request margin)                 rounded up to a whole Mi
limit   = max(peak × (1 + limit margin), request)        rounded up to a whole Mi

The margins come from the sensitivity, workload type and environment you choose; the sizing model explains them, and they are assumptions too.

A request can't be larger than its limit: the API rejects it. So when the peak is so close to the average that the peak-based limit falls below the request, the limit is raised to the request. Kubernetes docs

Worked example

Average 410 MiB, peak 630 MiB, generic workload, medium sensitivity, production, 3 replicas:

request410 MiB × 1.30 = 533 MiB533Mi
limit630 MiB × 1.30 = 819 MiB, above the request819Mi
total request533Mi × 3 replicas1599Mi

When the peak is close to the average, the request can decide the limit. Average 1000 MiB and peak 1010 MiB, high sensitivity:

request1000 MiB × 1.50 = 1500 MiB1500Mi
limit1010 MiB × 1.40 = 1414 MiB, below the request1500Mi

03 Guaranteed: request equal to limit

request = limit = max(peak × (1 + limit margin),
                      average × (1 + request margin))
                  rounded up to a whole Mi

A Pod is Guaranteed only if every container has a memory request equal to its memory limit and a CPU request equal to its CPU limit. The calculator only writes memory, so the note under the result reminds you to set CPU the same way; without it the Pod stays Burstable. Kubernetes docs

Google's GKE guidance recommends the same amount of memory for the request and the limit, because memory can't be compressed: when it runs out, the Pod has to be taken down. GKE docs The calculator still defaults to Burstable, which packs more Pods per node; choose Guaranteed for workloads that mustn't be evicted. Assumption

request = limit630 MiB × 1.30 = 819 MiB, the larger of 819 and 533 MiB819Mi
total request819Mi × 3 replicas2457Mi

04 Every warning, and why

Message aboutShown whenBasis
Limit far above the request warning The limit is more than 4× the request The scheduler places Pods by their requests, and under node memory pressure Pods above their requests are evicted first. Kubernetes docs A LimitRange can cap the ratio (maxLimitRequestRatio) but has no default. Kubernetes docs The 4× threshold is ours. Assumption
Peak below average error The peak you entered is lower than the average Impossible with real samples; it usually means two different series. See the sizing model.

For example, a worker averaging 100 MiB with a 600 MiB peak, at high sensitivity:

request100 MiB × 1.40140Mi
limit600 MiB × 1.751050Mi
limit ÷ requestabove 4, so the warning shows7.5×

05 Compared with the Vertical Pod Autoscaler

Kubernetes itself doesn't publish a formula for memory requests. Its Vertical Pod Autoscaler (VPA), maintained by the Kubernetes autoscaling group, does recommend one. Its defaults (recommender flags):

VPA recommenderDefault
Peak memory usage is taken per interval of24 hours (memory-aggregation-interval), over 8 intervals
Target is this percentile of those peaks90th (target-memory-percentile)
Safety margin added to the recommended request15% (recommendation-margin-fraction)
Minimum recommendation per Pod250 MB (pod-recommendation-min-memory-mb)
Memory bump-up when an OOM kill occursratio 1.2 (oom-bump-up-ratio), at least 100 MiB (oom-min-bump-up-bytes)

When VPA also sets limits, it keeps each container's limit-to-request ratio. Kubernetes docs

The difference that matters: VPA sizes the request from daily peaks, while this calculator sizes it from the average. So VPA would recommend a higher request, and a Pod sized here spends more of its time above its request, where it can be evicted under node memory pressure. The calculator keeps the average because it works from as few as one or two samples; reproducing VPA needs at least a day of samples with timestamps. If eviction is a concern, choose a higher sensitivity or Guaranteed QoS, or let VPA size the request once the workload has history. Assumption

Request basis: VPA-style

The calculator's Request basis field can size the request the way VPA does instead. VPA's recommender adds its 15% margin to the memory target and never recommends less than 250 MiB for a Pod, split between its containers. Kubernetes source

request = max(peak × 1.15, 250 MiB)    rounded up to a whole Mi
limit   = max(peak × (1 + limit margin), request)

VPA's target is the 90th percentile of daily peaks; with only a peak to go on, the calculator uses the peak, which is at least as high, so the request comes out at or above what VPA would set. Assumption The sensitivity, workload and environment margins don't apply to the request in this mode, only to the limit. The 250 MiB minimum is applied in full, as if the Pod had one container. Assumption

request630 MiB × 1.15 = 724.5 MiB725Mi
limit630 MiB × 1.30 = 819 MiB819Mi
total request725Mi × 3 replicas2175Mi

06 What to paste

container_memory_working_set_bytes{namespace="prod", container="api"}
  • container_memory_working_set_bytes is a gauge of the container's current working set, in bytes. cAdvisor docs
  • The working set is what the kubelet measures to decide when a node is short of memory, which is why it's the metric to size from. Kubernetes docs container_memory_usage_bytes instead counts all memory "regardless of when it was accessed", as cAdvisor puts it.
  • A range query over a representative period (a week is a good default) gives the best average and peak. Series with container="" (the whole Pod) and container="POD" (the pause container) are skipped. These are the label values cAdvisor commonly exports for them; we haven't found them documented. Assumption

07 All assumptions in one place

Besides the margins of the shared sizing model:

Our default: a value we chose. Our reading: how we read documentation that isn't explicit. About your setup: something we take for granted about your data or cluster.

AssumptionKindWhyIf it doesn't hold
Warn when the limit is over 4× the request ↩Our defaultA judgment call on when overcommit makes evictions likelyOnly the warning moves; a LimitRange in your namespace may set a stricter cap.
The request comes from the average, not from daily peaks like VPA ↩Our defaultWorks with few samplesThe Pod is more often above its request, so more likely to be evicted under node pressure; choose VPA-style as the request basis to avoid it.
Burstable by default ↩Our defaultPacks more Pods per nodeGKE recommends request = limit for memory; choose Guaranteed for workloads that mustn't be evicted.
container="" and container="POD" are Pod-level and pause series ↩Our readingWhat cAdvisor commonly exportsIf your setup labels them differently, they're averaged in and skew the result; filter them out in the query.
VPA-style uses the peak as VPA's target ↩Our defaultThe calculator has a peak, not 8 days of daily peaksThe request is at or a little above what VPA would recommend.
VPA's 250 MiB minimum goes to one container ↩About your setupVPA splits it between a Pod's containers; the calculator sizes oneIn a multi-container Pod, VPA would give each container only its share of 250 MiB.

Values you can change

The calculator’s Advanced: margins and defaults section, closed by default, lets you replace these values when your setup differs. Each field’s “?” says how it moves the result; a value outside the range is used at its nearest end, and “Reset to defaults” puts them all back.

ValueDefaultRangeWhere the default comes from
Request marginfrom the profile0–200%MemoryLimit’s default, from sensitivity, workload type and environment (sizing model); sizes the request
Limit marginfrom the profile0–200%MemoryLimit’s default, from sensitivity, workload type and environment (sizing model); sizes the limit
Overcommit warning above4× the request1–20×Our default, assumption 1; only moves the warning
VPA margin (VPA-style only)15%0–100%The VPA recommender’s recommendation-margin-fraction default (flags); set your cluster’s value if it changes it
VPA minimum (VPA-style only)250 MiB0–4,096 MiBThe VPA recommender’s pod-recommendation-min-memory-mb default (flags)

08 References

← Back to the Kubernetes calculator