Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Kubernetes resource management becomes predictable when you separate three decisions: requests tell the scheduler how much capacity a Pod needs to be placed, limits constrain runtime consumption, and autoscalers change either replica count, per-Pod sizing, or node capacity. Set requests from representative measurements, apply limits according to the workload’s failure tolerance, and select HPA, VPA, node autoscaling, or a combination based on the bottleneck you need to change.

There is no reliable universal request-to-limit ratio. A latency-sensitive API, a batch worker, and a memory-heavy cache have different safe settings. The Kubernetes documentation defines the mechanisms and their consequences; your measurements and operating requirements determine the values.

Requests and limits answer different questions

A container’s resources.requests answers: “How much of this resource should the scheduler reserve when placing the Pod?” A limit answers: “What runtime ceiling or enforcement behavior should the container receive?” Confusing the two is a common cause of unschedulable workloads, throttling, and unexpected evictions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Requests guide placement

When you specify resource requests, the kube-scheduler compares the Pod’s requested resources with the allocatable resources on candidate nodes. As the Kubernetes documentation puts it: “When you specify the resource request for containers in a Pod, the kube-scheduler uses this information to decide which node to place the Pod on.” The scheduler does not place a Pod solely according to the node’s current observed utilization.

A request is not normally a runtime ceiling. If a container requests 500 millicores and its node has spare CPU, it can use more than 500 millicores, subject to its limit and the node’s actual contention. Conversely, a request that is set too high can prevent scheduling even when monitoring shows low current usage, because the scheduler must reserve the declared amount.

Limits are enforced at runtime

Kubernetes passes limits to the container runtime, which uses Linux control groups and kernel behavior on Linux nodes. CPU and memory limits behave differently:

  • CPU limit: a hard ceiling implemented through throttling. A process can remain healthy but receive less CPU time when it reaches the configured limit.
  • Memory limit: reactive enforcement. If usage exceeds the limit and the kernel detects memory pressure, it may terminate a process with an out-of-memory (OOM) kill. Crossing the limit does not guarantee an immediate kill at the exact instant of the overage.

These consequences mean that raising a memory limit can prevent avoidable OOM terminations but also allows a faulty process to consume more node memory. Lowering a CPU limit can protect neighbors while increasing latency if the workload regularly needs bursts.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Pod totals are sums of container values

For ordinary container-level resources, a Pod’s request or limit for a resource is the sum of that resource’s corresponding values across its containers. Include sidecars, service-mesh proxies, log shippers, and init-container behavior in your capacity model. A main application requesting 500m CPU plus a sidecar requesting 100m produces a 600m CPU request for scheduling purposes.

Pod-level resource specification is a separate, version-sensitive feature. The cited Kubernetes resource documentation describes Pod-level requests and limits as an alpha feature beginning in Kubernetes v1.32 and disabled by default in that release description. Check the documentation for the exact version and feature gates running in your cluster before using it.

CPU and memory quantities use different units

CPU quantities are expressed in cores or millicores. One CPU represents one physical or virtual core as exposed by the node. Fractional values are valid: 0.1 CPU equals 100m. Kubernetes does not support CPU precision finer than 1m, or 0.001 CPU.

Memory quantities represent bytes. Decimal suffixes such as M and binary suffixes such as Mi are not interchangeable: 1M is 1,000,000 bytes, while 1Mi is 1,048,576 bytes. Case matters. The particularly dangerous typo is 400m in a memory field: it means 0.4 bytes, not 400 megabytes. 400Mi means 400 mebibytes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Resource Valid examples What to check
CPU 500m, 1, 0.25 Use millicores or decimal cores; values finer than 1m are not supported.
Memory 256Mi, 1Gi, 500M Choose decimal or binary suffixes deliberately and preserve the capitalisation.

Set values from measurements, not a fixed ratio

Start with representative load: normal traffic, expected peaks, startup behavior, garbage collection, queue backlogs, and failure scenarios. Capture CPU and memory over enough time to include periodic jobs and traffic cycles. Then choose values according to the consequence you are willing to accept.

A practical sizing workflow

  1. Describe the workload contract. Record latency objectives, throughput, restart tolerance, batch deadlines, and whether a short burst is preferable to queuing.
  2. Measure each container. Separate the application from sidecars. Look at CPU usage, working-set memory, peak memory, restarts, throttling, and OOM events under representative load.
  3. Set the CPU request near sustained demand. The request should cover the CPU needed for normal service so scheduling and utilization-based autoscaling have a meaningful baseline. Do not use a momentary idle reading.
  4. Set the memory request for expected resident usage. Include language-runtime overhead, caches you intend to keep, and sidecars. Memory is not compressible like CPU; sustained pressure can lead to eviction or OOM behavior.
  5. Choose limits as an operational boundary. A CPU limit can cap noisy bursts but may throttle a latency-sensitive service. A memory limit should be above normal peaks with a margin justified by measurements, while still protecting the node from runaway growth.
  6. Load-test and observe. Confirm scheduling, latency, throttling, restarts, and node pressure. Revise one variable at a time and record why it changed.

Requests influence both placement and utilization calculations. Limits influence enforcement. Treat those as separate tuning loops rather than deriving one value mechanically from the other.

Example manifest

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: example/api:2.4
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1"
            memory: "1Gi"

In this example, the scheduler accounts for 500m CPU and 512Mi memory per Pod. The container may use more CPU than 500m when available, up to the 1 CPU limit, and may be throttled at that ceiling. Memory can grow above 512Mi, but approaching or exceeding 1Gi under pressure can result in OOM termination.

Node capacity is less than the headline node size

Nodes reserve part of their raw capacity for the operating system, kubelet, container runtime, and other system daemons. Scheduling uses node allocatable capacity after those reservations, not the advertised raw CPU and memory total.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This explains two apparently contradictory observations: a node can show low instantaneous utilization while a new Pod remains pending because its request does not fit, and a cluster can show apparently available capacity while pressure still causes evictions because system and workload reservations leave little allocatable headroom. Check allocatable values and pending-Pod events before reducing requests simply to make a Pod schedule.

Requests that are too low can also distort utilization-based autoscaling and pack nodes so tightly that ordinary bursts create contention. Requests that are too high reduce bin-packing efficiency and may trigger additional nodes. Neither effect proves a particular percentage of cost savings; the result depends on workload behavior, node types, limits, and capacity availability.

Choose the autoscaler that changes the bottleneck

Kubernetes has separate autoscaling mechanisms. The Kubernetes documentation describes autoscaling as the ability to automatically update an object that manages a set of Pods, such as a Deployment. In practice, identify whether you need more copies, larger copies, or more places to run them.

Mechanism What changes What drives it Operational requirements and limits
Horizontal Pod Autoscaler (HPA) Replica count for a workload Observed resource utilization or other configured metrics Part of the Kubernetes API. Resource-utilization calculations use resource requests; utilization is calculated across containers in a Pod, which can hide one container’s individual saturation.
Vertical Pod Autoscaler (VPA) Resource requests and limits for workload Pods Historical utilization, available cluster resources, and events such as OOM conditions Installed separately as a CustomResourceDefinition and controller. Applying recommendations can require Pod restarts, depending on the update policy.
Node autoscaling Number or capacity of cluster nodes Unschedulable Pods, scheduling constraints, and autoscaler configuration Works at the infrastructure layer. Provisioning limits, incompatible node settings, or unavailable cloud capacity can prevent desired nodes from appearing.

When HPA is the right change

Use HPA when one replica has an appropriate size but demand varies across time. CPU- or memory-utilization targets are interpreted relative to requests, so a missing or unrealistic request produces a misleading signal. For example, a Pod using 400m CPU with a 100m request reports 400% CPU utilization, while the same usage against an 800m request reports 50%.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

HPA sums resource usage across containers in a Pod. A lightly used application container can mask a saturated sidecar, so inspect per-container metrics when a Pod-level target does not match user-visible performance. HPA increases or decreases replicas; it does not enlarge an individual container’s request or limit.

When VPA is the right change

Use VPA when the recurring problem is incorrect per-Pod sizing: chronic under-requesting, excessive reservations, or memory growth that cannot be solved by adding replicas. VPA uses historical observations, available cluster resources, and signals such as OOM events to recommend or apply new values. Because changing resources can require recreation of Pods, evaluate disruption budgets, startup time, and state handling before enabling an update policy.

The cited documentation identifies VPA as stable since Kubernetes v1.25, but installation and feature behavior remain version-dependent. Verify the VPA release that supports your cluster version and read its update-policy documentation before allowing automatic changes.

When node autoscaling is the right change

Use node autoscaling when Pods are correctly sized but cannot be placed because allocatable capacity is exhausted or the required node shape is absent. It reacts to scheduling constraints rather than merely to average utilization. A node autoscaler cannot fix a Pod whose request is larger than every permitted node, a workload blocked by affinity or taints, or a cluster that has reached configured limits or available capacity.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Node autoscaling can be combined with VPA: VPA changes the Pod’s resource request, and node autoscaling can then add a node on which that larger request fits. They solve different layers of the problem.

QoS classes affect behavior during node pressure

Kubernetes assigns every Pod a quality-of-service (QoS) class from the requests and limits of its containers. The class is one input to eviction decisions when a node experiences pressure; it is not an immunity guarantee.

  • Guaranteed: every container has CPU and memory requests, and each request equals its corresponding limit.
  • Burstable: the Pod has at least one request or limit, but does not meet all Guaranteed conditions.
  • BestEffort: no container has CPU or memory requests or limits.

Review the resulting QoS class after changing sidecars or injecting agents. A single container without matching values can change the Pod’s classification and its relative treatment during pressure. Regardless of class, a node with insufficient memory can evict workloads, and a container can still be OOM-killed for exceeding its own memory limit.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Memory-backed temporary storage needs its own budget

An emptyDir volume configured with medium: Memory consumes memory rather than disk. Without a sizeLimit, it can consume up to the Pod’s memory limit when a memory limit is defined. Without a memory limit, the volume can consume node memory subject to the documented behavior, increasing pressure on other workloads.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Include caches, unpacked archives, and temporary files in the memory budget. Set a volume size limit where appropriate, and monitor both container working-set usage and the volume’s growth; a container can appear within its application allocation while its memory-backed temporary files push the node toward pressure.

Version-aware checks before rollout

Resource semantics such as requests, limits, units, and QoS are long-standing Kubernetes concepts, but feature maturity and installation requirements change. The cited official material identifies HPA as stable since v1.30, VPA as stable since v1.25, and Pod-level resource specification as alpha beginning in v1.32. Treat those statements as release-specific: compare them with the documentation for the exact Kubernetes distribution and version you operate.

  • Confirm the metrics pipeline required by your HPA targets is installed and returning values.
  • Confirm VPA controllers and custom resources are installed before applying a VPA object.
  • Check feature gates before using alpha Pod-level resources.
  • Read the node autoscaler documentation for your provisioning integration, limits, and capacity constraints.

Troubleshoot the symptom instead of changing every value

Pod remains Pending

Inspect scheduler events and compare the Pod’s summed requests with each node’s allocatable capacity. Check taints, tolerations, affinity, topology constraints, and whether the request exceeds the largest permitted node. Reducing a request without measuring the workload may make placement succeed while creating contention later.

CPU throttling or high latency

Check whether the CPU limit is lower than observed burst demand and whether throttling coincides with latency. If sustained demand is legitimate, raise the limit or remove it only after confirming node-level isolation and fairness requirements. Raising the request alone changes scheduling and HPA math; it does not remove a CPU limit.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

OOMKilled containers

Determine whether the process exceeded its container memory limit or the node was under pressure. Inspect restart reasons, peak working-set memory, garbage-collection behavior, and memory-backed volumes. Increase the limit only when the node and workload budget can support it; otherwise fix the leak, cache growth, or concurrency that causes the peak.

HPA scales unexpectedly or does not scale

Verify that requests are present and realistic, metrics are available, and the target is based on the resource you intend to control. Compare aggregate Pod utilization with per-container metrics, because a sidecar can dominate the sum or hide application-specific saturation.

Node autoscaling does not add capacity

Check pending-Pod events, node-group limits, allowed instance shapes, affinity and taints, quotas, and current infrastructure capacity. A node autoscaler cannot provision a node that violates those constraints or a node type that is unavailable.

A repeatable operating checklist

  • Measure representative normal and peak behavior for every container.
  • Set requests to support placement and meaningful utilization percentages.
  • Set CPU limits only when throttling is an acceptable trade-off.
  • Set memory limits with room for measured peaks, and account for memory-backed emptyDir data.
  • Review summed Pod requests, node allocatable capacity, and sidecar overhead.
  • Select HPA for replica demand, VPA for per-Pod sizing, and node autoscaling for cluster capacity.
  • Validate QoS classification and pressure behavior after each resource-policy change.
  • Recheck version-specific feature status and controller prerequisites before production rollout.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.