Cloud

Kubernetes Resource: Limits, Requests, HPA in Production

Kubernetes Resource: Limits, Requests, HPA in Production

Kubernetes Resource Management: Production Checklist for Limits, Requests, and HPA

Efficient resource management in Kubernetes is the cornerstone of any stable and high-performing cloud-native infrastructure. Ignoring this aspect can transform a dynamic and resilient environment into a minefield of instability and unexpected downtime. Imagine a scenario: a well-sized Kubernetes cluster with dozens of deployments handling critical workloads. Everything seems to be working perfectly until a single pod, perhaps due to a memory leak or an unexpected traffic spike, begins to consume resources disproportionately. Without the right controls, this pod can completely saturate a node, leading to the forced eviction of all other pods residing on it. This is not a theoretical exercise; I personally witnessed a cluster with 30 deployments go down for 20 minutes, precisely because of a pod with a memory leak that saturated the node’s RAM. The cause? The absence of just five lines of YAML configuration related to resource limits. A trivial error that had a significant impact on service availability. This article aims to be a practical guide and an operational checklist for correctly configuring requests, limits, QoS classes, and autoscaling, ensuring stability and performance for your production Kubernetes environment.

Tested on: Kubernetes 1.29 · kubectl 1.29 · July 27, 2026

Prerequisites / Test Environment

To follow this guide, you will need a working Kubernetes cluster and kubectl access. A production environment is not necessary; a local cluster like Minikube or Kind is sufficient for testing these concepts. Ensure you have kubectl configured and authenticated to your cluster.

1. Requests and Limits: Difference and Why Both Are Mandatory

The distinction between requests and limits is fundamental for the stability and efficiency of your Kubernetes cluster. These two parameters, defined for CPU and memory, guide the Kubernetes scheduler in placing pods on nodes and kubelet in managing resources on the node.

  • Requests: Indicate the minimum amount of resources (CPU and memory) a pod requires to function correctly. The scheduler uses requests to decide which node to place a pod on, ensuring the node has enough available resources to meet this minimum requirement. If a node does not have the requested resources, the pod will not be scheduled on that node. Read also: Kubernetes Networking: DNS, Services, Ingress para Sysadmins
  • Limits: Represent the maximum amount of resources (CPU and memory) a pod can consume. If a pod attempts to exceed its memory limit, it will be terminated (OOMKilled – Out Of Memory Killed) by the kubelet. If it exceeds its CPU limit, its execution will be throttled, but it will not be terminated. Limits are crucial to prevent a single pod from starving other pods on the node, or even causing instability to the entire node, as in the memory leak example I mentioned.

Why are both mandatory? Without requests, Kubernetes cannot guarantee a minimum resource baseline, leading to over-provisioning and instability. Without limits, a misbehaving pod can compromise the entire node. The combination of both provides the scheduler and kubelet with the necessary information for predictable and robust resource management.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: nginx:latest
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m" # 0.25 CPU core
          limits:
            memory: "128Mi"
            cpu: "500m" # 0.5 CPU core

2. QoS Classes: Guaranteed, Burstable, BestEffort

Kubernetes assigns each pod a Quality of Service (QoS) Class based on its requests and limits configuration. This class determines scheduling priority and, crucially, eviction management in situations of resource scarcity on the node.

  • Guaranteed: A pod is Guaranteed if the CPU and memory requests are equal to the limits for all its containers. These pods have the highest priority and are the last to be terminated in case of insufficient resources on the node.
  • Burstable: A pod is Burstable if it has at least one CPU or memory request configured, and requests are less than limits (or limits are not specified). These pods have an intermediate priority and may be terminated before Guaranteed pods.
  • BestEffort: A pod is BestEffort if none of its containers specify requests or limits for CPU or memory. These pods have the lowest priority and are the first to be terminated in case of resource scarcity.

Understanding QoS Classes is crucial for resilience. Assign Guaranteed to critical workloads, Burstable for most applications, and BestEffort only for non-essential services or batch jobs that can tolerate interruptions.

3. LimitRange and ResourceQuota for Namespaces

In multi-tenant environments or with different teams sharing a cluster, it is essential to enforce resource usage policies at the namespace level. LimitRange and ResourceQuota are the tools for this.

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-mem-limit-range
spec:
  limits:
  - default:
      cpu: 500m
      memory: 256Mi
    defaultRequest:
      cpu: 200m
      memory: 128Mi
    type: Container
  • ResourceQuota: Limits the total resource consumption for an entire namespace. You can limit the number of pods, services, persistent volumes, and most importantly, the total requests and limits for CPU and memory. This prevents a single namespace from monopolizing cluster resources.
kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-quota
spec:
  hard:
    requests.cpu: '4'
    requests.memory: 8Gi
    limits.cpu: '8'
    limits.memory: 16Gi
EOF

These tools, when well-configured, allow you to rest easier, knowing that teams cannot inadvertently (or intentionally) cause problems for the entire cluster.

4. HPA — Autoscaling Based on CPU and Custom Metrics

The Horizontal Pod Autoscaler (HPA) is a controller that automatically scales the number of replicas of a Deployment, ReplicaSet, or StatefulSet based on observed CPU, memory, or other custom metrics. This allows you to manage load spikes without manual intervention.

The HPA monitors metrics via the metrics.k8s.io API (which requires metrics-server to be installed) or external APIs for custom metrics. When the average resource utilization of a pod exceeds a defined threshold, the HPA increases the number of replicas. When it drops, it reduces them.

Example of CPU-based HPA:

kubectl autoscale deployment myapp --cpu-percent=70 --min=2 --max=10

This command creates an HPA that will maintain the average CPU utilization of the myapp deployment at 70%, scaling between a minimum of 2 and a maximum of 10 pods. You can check the HPA status with:

kubectl get hpa

For custom metrics, such as the number of HTTP requests per second or the length of a message queue, it is necessary to integrate a monitoring system like Prometheus and configure a Custom Metrics API to expose these metrics to the HPA.

5. VPA — Vertical Autoscaling to Optimize Requests

While HPA scales horizontally (adding or removing pods), the Vertical Pod Autoscaler (VPA) scales vertically, dynamically adjusting CPU and memory requests and limits for individual pods. The VPA observes a pod’s historical resource usage and suggests (or directly applies) optimal configurations.

VPA is particularly useful for workloads with variable resource usage patterns that do not benefit from horizontal scaling, or for optimizing resources and reducing waste. It can operate in different modes:

  • Off: Only suggests optimal values, does not apply them.
  • Initial: Applies suggestions only when the pod starts.
  • Recreate: Terminates and recreates pods to apply new values.
  • Auto: Dynamically adjusts resources without recreating the pod (requires beta Kubernetes features).

VPA implementation is more complex than HPA and requires careful evaluation, especially for Recreate mode, which involves temporary downtime for the pod.

6. kube-resource-report: Cluster Overview in One Command

To get an overview of resource usage and configuration in your cluster, tools like kube-resource-report or even simple kubectl commands are indispensable. For a quick and straightforward analysis of current resource usage, you can use:

kubectl top pods --all-namespaces --sort-by=cpu

This command will give you an immediate overview of the pods consuming the most CPU, useful for identifying potential problems or misconfigured pods. For a more in-depth analysis and aggregated reports, external tools like kube-resource-report or monitoring dashboards (e.g., Grafana with Prometheus) are essential for a production environment. Read also: Prometheus Alerting: Telegram, Email, PagerDuty with AlertManager

Common Errors and Troubleshooting

  • Frequent OOMKilled: Indicates that memory limits are too low or that there is a memory leak in the application. Increasing the limit can temporarily resolve it, but it is crucial to investigate the cause of excessive consumption.
  • Pod Pending: Often means that CPU or memory requests are too high, and there are no nodes with sufficient resources to schedule the pod. Check kubectl describe pod for details.
  • CPU Throttling: If CPU limits are too low, the application may experience slowdowns. Monitor CPU usage and increase limits if necessary, but be careful not to over-provision.
  • HPA not scaling: Verify that metrics-server is installed and running (kubectl top pods should work). Check HPA events (kubectl describe hpa ) to understand why it is not scaling.
  • Forgetting requests: This is a common error that leads pods to have BestEffort QoS, making them vulnerable to eviction in case of resource scarcity. Use LimitRange to set defaults.

FAQ — Frequently Asked Questions

Should I always set both requests and limits?

Yes, for most production workloads, it is strongly recommended to set both requests and limits. Requests help the scheduler place pods correctly, while limits prevent a single pod from compromising the entire node. Their combination ensures Guaranteed or Burstable QoS, reducing the risk of eviction.

What is the practical difference between HPA and VPA?

HPA (Horizontal Pod Autoscaler) increases or decreases the number of pods (horizontal scaling) based on load. VPA (Vertical Pod Autoscaler) adjusts a single pod’s resources (CPU/memory) (vertical scaling). HPA is ideal for stateless and scalable applications, while VPA is for optimizing resource utilization of single or stateful pods.

How can I monitor my cluster’s resource usage?

For basic monitoring, kubectl top nodes and kubectl top pods are a good start. For more advanced, production-grade monitoring, integration with Prometheus and Grafana is the de facto standard. These tools allow you to visualize historical usage, set alerts, and analyze trends, which are essential for capacity planning. For official documentation on Kubernetes monitoring, refer to the Kubernetes Monitoring documentation.

Can a pod with Guaranteed QoS still be terminated?

Yes, even a Guaranteed pod can be terminated, but it is a last resort. This can happen in extreme situations, such as a lack of critical system resources (e.g., PIDs, disk space) or if the node itself fails (e.g., hardware crash, kernel panic). The Guaranteed class offers maximum protection, but not absolute immunity in case of node failures.

Conclusions with Operational Takeaways

Resource management in Kubernetes is not an option, but a fundamental practice for the stability and efficiency of production environments. The 20-minute downtime incident due to 5 missing YAML lines is a powerful warning. Properly implementing requests and limits for each pod, using ResourceQuota and LimitRange to enforce namespace-level policies, and leveraging autoscaling with HPA and VPA, are crucial steps to building a robust and resilient Kubernetes infrastructure. Do not let a misconfigured pod ruin your day. Invest time in understanding and implementing these best practices; it will pay off in terms of uptime and peace of mind.

Updated: July 2026

Share this article:

Written by

Rosario Giordano

Rosario Giordano is a system administrator and IT consultant specializing in cybersecurity and cloud, with over 20 years of experience managing enterprise Linux infrastructures. His areas of expertise include SSH hardening, Kubernetes platforms, PostgreSQL databases, VMware/ Proxmox virtualization, and compliance with NIS2 and ISO 27001 security frameworks