A HorizontalPodAutoscaler stuck at one replica while your pods are visibly saturated is one of the most common β and most misdiagnosed β incidents in a Kubernetes platform. The usual reaction is to lower the CPU target, add replicas manually, or blame "the autoscaler". None of that fixes the root cause.
In practice, an HPA that does not scale almost always falls into one of four buckets: the metrics pipeline is broken, the workload has no resource requests, the target threshold is mathematically unreachable, or the scaling behavior (stabilization window, policies) is deliberately throttling the decision. This article walks through each of them with real commands, then shows how to move past CPU/memory with custom metrics and KEDA.
Context: why the HPA looks broken when it is not
The HPA controller runs inside kube-controller-manager and reconciles every 15 seconds by default ( --horizontal-pod-autoscaler-sync-period ).β¦