Contents
What Are The Types Of Autoscaling In Kubernetes? What Is HPA In Kubernetes? Kubernetes HPA Explained: How Does Horizontal Pod Autoscaling Work? How Is HPA Scaling Calculated? What Are The Benefits Of HPA In Kubernetes? What Are The Limitations Of Kubernetes HPA? Kubernetes HPA Best Practices Frequently Asked Questions about the Kubernetes Horizontal Pod Autoscaler

It’s hard to predict the precise amount of resources a new Kubernetes workload requires for optimal performance. And, as your workload evolves, that initial resource consumption will also change. That’s where Kubernetes HPA (the Horizontal Pod Autoscaler) comes in — it lets your cluster automatically adjust pod counts based on real-time demand.

Scalability enables you to expand your system’s capacity during high demand, and release that additional capacity when demand drops.

This scaling occurs at the cluster and pod levels in Kubernetes. When automated through tools like the horizontal pod autoscaler, your K8s environment can respond to workload changes rapidly without tedious manual configuration.

What Are The Types Of Autoscaling In Kubernetes?

Kubernetes supports three types of autoscaling:

Cluster autoscaling

Cluster autoscaling increases or decreases the number of worker nodes within a cluster. The process increases nodes when one or more pods are pending scheduling — as long as the cluster stays within the parameters you specified.

Cluster autoscaling releases excess worker nodes as they become idle to match the number of pods currently in use.

Vertical pod autoscaling

Vertical pod autoscaling increases or decreases the amount of CPU or memory within your existing pods’ containers as needed. This adjusts your CPU and memory capacity without increasing or decreasing the number of pods you have at the time.

The process does this by scaling the resource requests and limits of a container within stateful or stateless pods — although it is most ideal for stateful services.

Horizontal pod autoscaling

To meet demand, HPA increases or decreases the number of pod replicas in an application. This is our focus for the rest of this guide.

What Is HPA In Kubernetes?

HPA is the Kubernetes object that manages horizontal pod autoscaling. HPA is also a controller and a K8s REST API service layer.

Horizontal pod autoscaling is the process that automatically increases or decreases the number of pods based on your workload’s CPU or memory usage, custom metrics from within Kubernetes, or external metrics (from outside the cluster).

  • The CPU and memory option tracks real-time resource usage, and when usage exceeds a pre-set percentage (or a raw value), HPA triggers the addition of new pod replicas to bring pod utilization closer to your desired level.
  • Custom metrics comprise other pod usage metrics besides CPU utilization. Custom metrics include client requests per second, I/O writes per second, network traffic, or some other value related to the pod’s use case. You can expose custom metrics using tools like the Prometheus Adapter, which translates application-level metrics into a format the HPA controller can consume through the custom.metrics.k8s.io API.
  • External metrics track values unrelated to pods, such as the number of queued tasks in a message broker like Amazon SQS or RabbitMQ. These are accessible through the external.metrics.k8s.io API and are useful for event-driven workloads where pod-level metrics alone do not capture demand.

For teams running event-driven architectures, KEDA (Kubernetes Event-Driven Autoscaling) extends HPA by adding native support for event sources like Kafka topic lag, database query volume, and cron schedules.

While vertical pod autoscaling scales your pod’s container CPU and memory capacity up (increase) or down, Kubernetes HPA adjusts your pods out (increase) or in (decrease/shrink) based on demand.

So, what does horizontal pod autoscaling actually look like in Kubernetes?

Kubernetes HPA Explained: How Does Horizontal Pod Autoscaling Work?

Horizontal pod autoscaling only works for workloads that can scale, so it won’t work with DaemonSets.

By default, the HPA controller works as part of the standard kube-controller-manager daemon. So it manages only the pods that a replication controller creates. Those include deployments, replica sets, or stateful sets.

You first define your desired autoscaling parameters. HPA follows the MIN and MAX number of replicas you define when adjusting your pods.

Each workflow has its own Horizontal Pod Autoscaler. Each Kubernetes HPA works through a control loop where it checks its workload’s metrics every 15 seconds against your set threshold. But you can use the horizontal-pod-autoscaler-sync-period controller to customize that interval.

For example, when your workload decreases, and your pod count exceeds your predefined minimum, the HorizontalPodAutoscaler triggers the Deployment, StatefulSet, or other similar workload resources to remove unused pods.

To detect when to scale out or in, HPA relies on metrics.

  • Metrics Server captures CPU and memory consumption data for nodes and pods. The autoscaling/v2 API — now the GA standard since Kubernetes 1.26 — supports scaling based on CPU utilization, memory usage, custom metrics, and multiple metrics within a single HPA object. The older autoscaling/v1 API only supports average CPU utilization and is no longer the recommended path. Since Kubernetes 1.27, HPA can also evaluate resource usage at the individual container level using the ContainerResource metric type, which prevents idle containers in multi-container pods from skewing scaling decisions.
  • To use external or custom metrics, you need to create an interface with a Kubernetes monitoring service or another source of metrics. You can do this through the custom.metrics.k8s.io API or external.metrics.k8s.io API.

Overall, the HPA scaling process is fast, automatic, and continuous.

How Is HPA Scaling Calculated?

The HPA controller uses a straightforward formula to determine the ideal replica count each time it runs its control loop:

desiredReplicas = ceil( currentReplicas × (currentMetricValue / desiredMetricValue) )

For example, if you have 4 replicas running at an average CPU utilization of 80%, and your target is 50%, the calculation produces: ceil(4 × (80 / 50)) = ceil(6.4) = 7. HPA would scale the deployment to 7 replicas.

When multiple metrics are defined, HPA calculates the desired replica count for each metric independently and uses the highest value. This ensures the workload is scaled to handle the most constrained resource.

To prevent rapid oscillation (known as “thrashing”), Kubernetes applies a stabilization window for scale-down events. The default is 5 minutes, configurable via the –horizontal-pod-autoscaler-downscale-stabilization flag. During this window, HPA considers the highest recommended replica count from recent calculations rather than immediately scaling down in response to a brief dip in usage. You can fine-tune both scale-up and scale-down behavior using the behavior field in the HPA spec, defining policies for the rate and window of scaling changes.

What Are The Benefits Of HPA In Kubernetes?

Horizontal pod autoscaling helps:

  • Continuously assesses your metrics to ensure your application is available at all times.
  • Automatically increase an application’s pods to meet increased workload, such as traffic volume or number of client requests, in order to sustain optimal performance.
  • Automatically decrease the number of an application’s pods when demand reduces to save costs.
  • Adjust the number of pod replicas according to the time of day you expect the highest or lowest demand.
  • Set specific capacity needs for specific periods, such as weekends, holidays, or off-peak hours.
  • Schedule capacity based on an event, for example, a code release.
  • Apply stabilization windows to prevent pods from terminating prematurely during brief usage fluctuations.

Yet horizontal pod autoscaling in Kubernetes has its limits.

What Are The Limitations Of Kubernetes HPA?

Some limitations of the Kubernetes Horizontal Pod Autoscaler include:

  • It doesn’t work with DaemonSets.
  • Only works if your cluster can add more pods without exceeding your pre-set parameters. Pair HPA with a cluster autoscaler to provision additional nodes when capacity runs short.
  • A pod may terminate frequently (thrashing) if its CPU and memory parameters are not set up correctly.
  • Even with HPA enabled, you can still waste resources if you overprovision for CPU or memory capacity.
  • While you can implement HPA and VPA together in the same cluster, avoid using both on CPU and memory simultaneously for the same workload, as simultaneous scaling events may produce inaccurate metrics.
  • If you set spec.replicas directly on a Deployment or StatefulSet, each manifest update will reset the replica count, overriding HPA’s decisions. Avoid hardcoding spec.replicas when HPA is managing the workload.
  • HPA is reactive, not predictive. It responds to metric changes after they occur, which means there is always a latency gap between a traffic spike and the new replicas becoming ready.
  • Kubernetes HPA ignores metrics related to disk read/writes, network I/O, and storage consumption, leading to inefficient allocation.
  • HPA’s dynamic scaling approach adds a layer of complexity to understanding Kubernetes costs. As such, you may need a robust Kubernetes cost optimization solution to help you track, analyze, and improve K8s cost visibility.

So, how can you make the most of Kubernetes HPA features?

Kubernetes HPA Best Practices

Take full advantage of the Kubernetes HorizontalPodAutoscaler by implementing the following best practices:

  1. Design your application for horizontal scaling from the start. Microservices architectures naturally support running parallel pods. If your application relies on local state or sticky sessions, address those before enabling HPA.
  2. Set resource requests for every container in every pod. HPA calculates utilization as a percentage of requested resources. Missing requests on even one container can corrupt HPA’s calculations, leading to inaccurate scaling decisions.
  3. Install Metrics Server on your cluster. HPA requires the metrics.k8s.io API to access per-pod resource data. Without Metrics Server, HPA has no data to act on.
  4. Use HPA alongside Cluster Autoscaler. HPA adds pods, but those pods need somewhere to run. Cluster Autoscaler provisions additional nodes when pod scheduling is blocked, and releases idle nodes as pods scale down. Together, they give you end-to-end elastic infrastructure.
  5. Avoid using VPA and HPA on CPU and memory for the same workload. Both use the same metrics for scaling decisions, and simultaneous adjustments can cause unpredictable behavior. Use VPA to right-size your resource requests first, then hand off to HPA for runtime scaling.
  6. Set your average utilization target between 50% and 80%. Lower targets make HPA more responsive but increase pod counts and costs. Higher targets improve efficiency but leave less headroom for sudden spikes while new replicas are spinning up. Most production workloads land around 60–70%.
  7. Configure stabilization windows to prevent thrashing. The default 5-minute downscale stabilization window works well for most cases, but workloads with predictable traffic patterns may benefit from longer windows. Use the behavior field in the HPA spec to set explicit scale-up and scale-down policies.
  8. Attach HPA to Deployments, not ReplicaSets directly. When you apply a rolling update to a Deployment, it creates a new ReplicaSet. If HPA targets the old ReplicaSet, it loses control after the update. Targeting the Deployment ensures HPA follows the workload through updates.
  9. Define Pod Disruption Budgets for critical applications. PodDisruptionBudgets prevent HPA from reducing replicas below a safe minimum during voluntary disruptions. This protects mission-critical workloads from scale-down events that could impact availability.
  10. Monitor HPA decisions, not just application metrics. Use kubectl describe hpa to inspect current targets, observed values, and recent scaling events. APM tools such as Grafana, Prometheus, or CloudZero for Kubernetes cost analysis can surface whether HPA is scaling efficiently or burning budget on unnecessary replicas.

Using third-party solutions such as Prometheus or Grafana can help solve this problem by providing more precise scaling with additional features, like alerting and dashboards.

  • Set your average pod utilization target at 50%-80%.

This range will ensure your app can handle unexpected peaks in traffic without scaling up. The lower your target value, the easier it is for HPA to kick in and scale your pods out, which may increase costs without necessarily enhancing performance.

  • However, you do not want to raise the average pod utilization target above 80%.

Otherwise, you may have an inadequate buffer to handle the increased load while new replicas are spinning up.

  • Monitor application performance to be sure.

APM metrics, such as CPU and memory usage, enable Kubernetes HPA to determine when and by how many pods to scale in and out. You can use open-source solutions like Grafana, ELK stack, and Prometheus or proprietary solutions like CloudZero (Kubernetes cost analysis), New Relic, and Sematext to check HPA’s accuracy and configure it accordingly.

  • More doesn’t always mean better.

Some DevOps professionals recommend using multiple HPAs for each deployment. The thinking is that this helps scale components or services individually, fine-tuning scaling. However, this can add costs, so consider what tradeoff to make, depending on your priorities.

  • Define Pod Disruption Budgets for high-priority applications.

PodDisruptionBudget prevents disruption to mission-critical pods running in your Kubernetes cluster. Specifying this for a particular application instructs autoscaler to avoid reducing replicas below the minimum amount you allocated in the disruption budget.

Speaking of budgets, you don’t want scalability to drain your Kubernetes budget. Yet almost no monitoring platform offers granular information about Kubernetes costs, despite tracking performance and security metrics.

Although many cost monitoring tools exist, most struggle to pinpoint who, what, and why your Kubernetes costs change. Yet, if you want to optimize Kubernetes costs at any scale, you need to know which components are costing you more than you intended.

CloudZero can help.

Kubernetes Complete Cost

CloudZero’s Kubernetes cost analysis uses a unique, code-driven approach to help you understand your K8s costs by key Kubernetes concepts, including cost per pod, cost per namespace, cost per container or microservice, cost per cluster, and more.

Dashboard

Better yet, CloudZero gives you insight into what drives your costs by showing your costs per service, deployment, environment, individual customer, product, feature, team, project, and other actionable insights.

By surfacing idle costs, CloudZero helps you increase your Kubernetes performance while reducing waste:

Bar Chart

CloudZero also detects cost anomalies in real-time. It then notifies you about abnormal cost patterns before they become costly issues.

Alerts

But don’t just take our word for it. to see how CloudZero can help you better understand, control, and optimize your Kubernetes spend!

Frequently Asked Questions about the Kubernetes Horizontal Pod Autoscaler