Build1 publisher3 min readPublished
A fully utilized node turns each extra HPA replica into a Pending pod
Replica count, pod size and node count each have one tool that can move them. A dev.to guide to HPA, VPA, KEDA and Karpenter puts the usual production autoscaling failures at the boundaries between those three levels.
The Engineer · Build desk

What happened
- The dev.to guide splits Kubernetes autoscaling into three independent levels: HPA and KEDA move replica counts, VPA adjusts per-pod CPU and memory requests, and Karpenter or Cluster Autoscaler change the node count.
- HPA can raise a deployment's replica count but cannot provision nodes, so when the existing nodes are fully utilized the extra pods stay in Pending.
- Kubernetes 1.35, from December 2025, made In-Place Pod Resizing generally available, and VPA 1.2 and later offer an InPlaceOrRecreate mode that changes requests without necessarily restarting the pod.
- KEDA 2.16 arrived in September 2026 with file-based authentication for ClusterTriggerAuthentication and new Kubernetes resource scalers, and the next version is scheduled for January 2027.
- Karpenter has largely replaced Cluster Autoscaler in AWS clusters, and its vendor claims 40 to 60 percent better node utilization than the older tool.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint GKE teams cannot follow the node-level advice yet, because no production-ready Karpenter provider for Google Cloud exists, so their node scaling stays inside predefined node groups.
- cost Moving HPA off CPU and onto RPS or queue depth requires a metrics adapter such as the Prometheus Adapter in the cluster, so the escape from metric collisions costs a component someone has to run.
- decision The restart was the main reason to keep VPA out of production, per the guide, so anyone who made that call is deciding again against different evidence.
The Karpenter number comes from a comparison against the classic Cluster Autoscaler, which scales predefined node groups. Karpenter instead calls the cloud API for the pods the scheduler could not place and picks the most cost-effective instance type that fits them, according to the dev.to guide [12]. The utilization gain transfers only where node groups are coarse enough to waste capacity and pod shapes varied enough that a per-pod instance choice beats a fixed one. Consolidation of underutilized nodes is how the slack comes back, and the guide describes it as aggressive [12], so the workloads have to tolerate eviction. A cluster running one pod shape on a well-matched instance type has less slack to recover.
The failure that costs the most to debug is the HPA/VPA death spiral, and it is division. Both tools read the same CPU metric. VPA lowers the request from historical data, and HPA then compares the same absolute usage against a smaller request, gets a higher percentage, and scales out [10]. Take a pod using 300 millicores against a 500m request: HPA sees 60 percent. Trim the request to 400m and the same 300m reads 75 percent, past a 70 percent target [2]. The guide's remedy is to split the signals: HPA on custom metrics such as RPS or queue depth, VPA on CPU and memory only, or VPA in Off mode where it writes recommendations and does not act [11]. Off mode leaves a human as the actuator. KEDA sits at the same level as HPA and reads queue depth; a misconfigured resource request is not something it can correct [3].
Scale-down timing is the other default worth reading before the incident rather than during it. HPA scales up aggressively and also scales down quickly, which can flap, and the guide recommends a stabilizationWindowSeconds of 300 for scale-down, a ceiling of 10 percent pod reduction per minute, and no delay on scale-up [5]. In wall-clock terms, taking 10 percent off the current count each minute, a 100-replica deployment needs seven steps to get under 50, and the five-minute window runs first, so about twelve minutes pass between the load dropping and the fleet halving [1].
Scale-to-zero is the capability KEDA adds over the classic HPA: more than 60 native scalers, including Kafka consumer lag and Redis list length, and a deployment that goes to zero replicas when no events are pending and back up when they arrive [6]. The KEDA HTTP Add-on buffers incoming requests and brings pods out of standby [8]. The guide's own pairings are conservative. A stateless, latency-sensitive web API gets HPA on CPU plus an RPS custom metric, VPA in Off mode, and Karpenter with a mix of Spot and On-Demand instances [15]. Queue-backed background workers get KEDA with scale-to-zero on Spot [16].
What to watch
- Whether the KEDA version planned for January 2027 adds more Kubernetes resource scalers or extends the HTTP Add-on.
- A production-ready Karpenter provider for Google Cloud; until one exists, GKE clusters stay on Cluster Autoscaler node groups.
- Whether VPA 1.2's InPlaceOrRecreate mode gets used in auto mode on latency-sensitive services now that in-place resizing is GA.