Kubernetes HPA formula
The HorizontalPodAutoscaler (HPA) changes a workload's replica count to keep a metric near a target. Every 15 seconds by default, it multiplies the current replicas by the ratio of the metric to its target and rounds up. The Kubernetes docs give this as the algorithm at its most basic:
desiredReplicas = ceil(currentReplicas
× currentMetricValue
÷ desiredMetricValue)50 replicas at 90% against a 75% target is a ratio of 1.2, so the HPA asks for 60, the example in the Kubernetes tolerance announcement. Utilization is a share of the pods' requests, not their limits. An AverageValue target compares raw values per pod instead, such as 120Mi against 100Mi, and the CPU and memory units converters explain how to read them.
This calculator also follows the steps in the controller's code, and the table in the result shows each one. It assumes all pods have the same request and no rollout is adding extra pods.
Why the HPA does nothing
The controller skips any change while the ratio is within the tolerance, 0.1 by default, and both ends count. Against a 60% target, anything from 54% to 66% stays put. It also drops the decimals of a percentage first, so 66.9% counts as 66%.
Rounding up can cancel a change too. 2 replicas at 59% against a 90% target make 1.31, which rounds up to 2. With min replicas at 1, that HPA scales down only at 45% or below. And a scale-down waits: by default the controller takes the highest recommendation of the last 5 minutes.
Why the formula says 12 and the HPA picks 8
4 pods at 180% against a 60% target ask for 12, but one step can only reach 8. The docs give one default: the larger of double the replicas or 4 more. The code follows it with a behavior block. With no behavior block, it uses the larger of double the replicas or 4 in total. The two differ only below 4 replicas: 1 pod can go to 5 with a block, and to 4 without. Custom scaling policies set their own limits, which this page doesn't calculate.
Pods that are not ready or have no metrics
On a CPU metric, the controller sets aside pods that have yet to become ready. A pod that started more than 5 minutes ago (the default) and was ready once counts as normal, even if it is not ready now. On other pod metrics, it sets aside only Pending pods. If it would still scale up, it counts them at 0% and works out the ratio again. With 2 ready pods at 60%, 1 not ready and a 30% target, the ratio of 2 falls to 1.3333, and the answer is 4, not 6. On a scale-down it multiplies by the ready pods alone: 3 ready pods at 30% and 2 not ready against 50% give 2, where the docs formula would give 3.
A pod with no metrics counts as 0% on a scale-up. On a scale-down, the docs say it counts as 100% of the target. The code agrees for AverageValue, but for Utilization it uses 100% of the pod's request, or the target if that is higher. This page follows the code. If the new ratio reverses the direction or lands inside the tolerance, nothing changes. kubectl get hpa shows the average from before this recount, over the ready pods only, so enter that figure here. Object and External metrics skip these steps.
Once you have a replica count, the pod capacity calculator shows how many nodes it needs.
FAQ
How does the Kubernetes HPA calculate desired replicas?
It multiplies the current replicas by the current metric value divided by the target, then rounds up: ceil(currentReplicas × currentMetricValue ÷ desiredMetricValue). 50 replicas at 90% against a 75% target gives 60. The controller skips the change when the ratio is inside the tolerance, then applies min and max replicas and a limit on how far one scale-up can go.
What is the HPA tolerance?
How far the ratio of current to target can be from 1.0 before the HPA scales. The default is 0.1, set for the whole cluster with the kube-controller-manager flag --horizontal-pod-autoscaler-tolerance. Managed Kubernetes services may not let you change this flag. One HPA can set its own with behavior.scaleUp.tolerance and behavior.scaleDown.tolerance, a feature that was alpha in Kubernetes 1.33, beta in 1.35 and stable in 1.37. Both ends count: against a 60% target, 54% and 66% change nothing.
Why is my HPA not scaling when the metric is above target?
Several things stop a scale-up. The ratio may be inside the tolerance, or the HPA may already be at max replicas. On a Utilization target, if any container in the pods has no request for the resource, utilization is undefined and the HPA takes no action for that metric. On a CPU metric, pods still starting count as 0% on a scale-up, which can bring the recalculated ratio back inside the tolerance. kubectl describe hpa shows the conditions behind it.
Why did the HPA add fewer pods than the formula says?
One scale-up has a limit. With no behavior block, the controller allows the larger of double the current replicas or 4 replicas in total. With a behavior block on default policies, it allows the larger of double the current replicas or 4 more. 4 pods at 180% against a 60% target ask for 12, and the first step goes to 8. The controller checks again every 15 seconds by default. Max replicas also caps the count, and on a CPU metric pods still starting count as 0%, which lowers the ratio.
How long does an HPA take to scale down?
About 5 minutes by default, once the metric has fallen far enough to lower the replica count and stays there. The controller uses the highest recommendation of the last 5 minutes, so a short dip changes nothing and a gradual fall comes down in steps. Set the window on one HPA with behavior.scaleDown.stabilizationWindowSeconds. The cluster-wide default is the kube-controller-manager flag --horizontal-pod-autoscaler-downscale-stabilization, which managed Kubernetes services may not let you change.
What happens when an HPA has several metrics?
The controller works out a replica count for each metric and picks the largest. If a metric cannot be read and the others suggest a scale-down, it skips scaling, but it can still scale up. To use this calculator, run it once per metric and take the largest result.