Kubernetes autoscaling automatically changes workload replicas or cluster capacity as demand changes, using measured signals and configured boundaries.
For small teams, the important distinction is that Pod autoscaling and node autoscaling solve different bottlenecks. A HorizontalPodAutoscaler (HPA) can add application replicas, but those Pods still need somewhere to run. Node autoscaling can add worker capacity when Pods cannot be scheduled, but it does not decide how many application replicas the workload should have.
This guide owns autoscaling inside the Kubernetes Cluster Management for Small Teams operating model. It explains HPA, node autoscaling, their interaction with resource requests, scale-down behavior, and the cost controls that matter on Raff. It does not duplicate the YAML-focused configuration work that belongs in a tutorial.
At Raff, the autoscaling rule is simple: do not automate a resource decision until the inputs are trustworthy. If CPU requests, minimum replicas, worker-pool bounds, or readiness behavior are guesses, autoscaling can automate the wrong decision faster.
Kubernetes autoscaling works at different layers
Kubernetes has several forms of autoscaling, and they should not be treated as interchangeable.
| Layer | What changes | Typical trigger | Main purpose |
|---|---|---|---|
| Horizontal Pod Autoscaler | Number of Pod replicas | CPU, memory, custom or external metrics | Match application capacity to demand |
| Vertical Pod Autoscaler | Pod CPU/memory recommendations or assignments | Historical/current resource use | Adjust resource sizing per Pod |
| Node autoscaler | Number of worker nodes | Unschedulable Pods and removable excess capacity | Match cluster capacity to scheduled workloads |
The most common small-team production pattern combines HPA plus node autoscaling.
HPA answers:
How many replicas should this workload run?
Node autoscaling answers:
Does the cluster have enough worker capacity to place those replicas?
Those questions are connected, but they happen at different layers.
For example:
Traffic rises ↓ HPA increases replicas ↓ New Pods are created ↓ Existing nodes fill up ↓ Some Pods remain Pending ↓ Node autoscaler adds worker capacity ↓ Pending Pods can schedule
The reverse path happens more slowly because safe scale-down needs to account for replica reductions, Pod movement, disruption rules, and whether a node can actually be removed.
HPA creates workload demand; node autoscaling turns unschedulable demand into infrastructure capacity.
HPA depends on metrics and realistic resource requests
The Kubernetes HorizontalPodAutoscaler periodically adjusts the desired replica count of a scalable workload such as a Deployment or StatefulSet. The stable autoscaling/v2 API can use CPU, memory, custom metrics, external metrics, or multiple metrics.
For resource-utilization targets, requests matter directly.
A simplified CPU-utilization relationship is:
CPU utilization ≈ measured CPU usage / CPU request
That means the same application usage can produce very different HPA signals depending on the request.
Example:
Measured CPU: 200m CPU request: 100m Utilization: about 200%
versus:
Measured CPU: 200m CPU request: 500m Utilization: about 40%
The workload is doing the same amount of CPU work. Only the request changed.
Kubernetes also documents an important failure mode: when the relevant resource request is missing for some containers, utilization for that Pod may be undefined and HPA may not act on that metric as expected.
That is why Kubernetes Requests vs Limits comes before autoscaling in this cluster. Requests are not only scheduling metadata; they can become the denominator of autoscaling decisions.
At Raff, we prefer to establish a measured request baseline before enabling aggressive HPA behavior. Otherwise a team can mistake bad requests for changing demand.
The HPA control loop is also intentionally not instantaneous. Kubernetes evaluates metrics periodically, handles missing data conservatively, and includes stabilization behavior designed to reduce replica flapping. Startup CPU spikes should be considered alongside readiness and startup probes so initializing Pods do not create misleading scale signals.
Official reference: Kubernetes Horizontal Pod Autoscaling.
Node autoscaling starts when Pods need capacity
Node autoscaling operates below the workload layer.
The Kubernetes project describes node autoscaling as automatically provisioning and consolidating Nodes to adapt to demand and optimize cost. A common scale-up signal is an unschedulable Pod: the scheduler cannot place it on existing nodes because its requirements do not fit the available capacity.
That requirement may involve more than CPU or memory. A Pod can remain unschedulable because of:
- insufficient requested CPU or memory capacity;
- node selectors or node affinity;
- taints and tolerations;
- topology constraints;
- volume or storage requirements;
- a node-pool maximum already being reached;
- an incompatible worker plan or pool configuration.
Adding “a node” therefore does not automatically solve every Pending Pod. The new capacity must be compatible with the Pod's scheduling requirements.
The upstream Kubernetes ecosystem commonly uses components such as Cluster Autoscaler for provider-integrated node scaling. Managed platforms may expose equivalent provider-managed behavior rather than requiring the user to operate that component directly.
Raff's public Kubernetes product behavior is worker-pool autoscaling: each pool can have minimum and maximum node counts, scale up when Pods cannot be scheduled, and scale down after sustained low load. The public product behavior should be treated separately from assumptions about the specific internal autoscaler implementation.
Official reference: Kubernetes Node Autoscaling.
HPA and node autoscaling form one feedback loop
Autoscaling becomes useful when the two layers reinforce each other without causing unnecessary oscillation.
Consider a web API with:
- 3 normal replicas;
- HPA minimum of 3 and maximum of 12;
- measured CPU requests;
- a worker pool with minimum and maximum node bounds.
During a traffic increase, HPA may request 6 replicas. If all six fit on current workers, the node count does not need to change. If only four fit, the remaining Pods can stay Pending until new worker capacity is available.
That distinction matters for cost.
A replica increase is not automatically a node increase.
The cluster pays for worker capacity, not for a theoretical Pod count. Efficient scheduling can absorb some HPA growth into existing headroom before another worker is needed.
Likewise, node scale-down should follow workload scale-down rather than race it. Once demand falls, HPA can reduce replicas. The node autoscaler can then evaluate whether workloads can be consolidated onto fewer workers without violating scheduling or disruption requirements.
This creates a practical order:
Demand changes ↓ Workload replicas adjust ↓ Scheduler evaluates placement ↓ Worker capacity adjusts if needed
A team should diagnose each layer separately. If HPA is not adding replicas, inspect metrics and HPA conditions. If replicas increase but Pods stay Pending, inspect scheduler events and worker-pool capacity. If workers scale but Pods still cannot run, inspect affinity, taints, storage, and topology constraints.
A Pending Pod is a capacity signal only after you know why the scheduler rejected it.
Cost control comes from bounds, requests, and headroom
Autoscaling does not inherently reduce infrastructure cost. It changes capacity automatically inside the rules you give it.
A badly configured autoscaler can increase cost just as efficiently as it can reduce it.
The most important cost controls are:
| Control | Cost effect | Reliability risk if too aggressive |
|---|---|---|
| HPA minimum replicas | Sets workload floor | Too low can reduce redundancy or warm capacity |
| HPA maximum replicas | Caps application expansion | Too low can prevent scale during demand spikes |
| Resource requests | Determines scheduler fit and utilization math | Too low creates contention; too high causes early scale-out |
| Worker-pool minimum | Sets paid infrastructure floor | Too low can reduce failure/maintenance headroom |
| Worker-pool maximum | Caps infrastructure expansion | Too low leaves Pods Pending under real demand |
| Scale-down policy | Determines how quickly excess workers leave | Too fast can cause churn or repeated scale-out |
| Node-pool shape | Determines packing efficiency | Wrong CPU/RAM ratio can waste one resource while exhausting another |
The cost objective should not be “run the fewest possible nodes.” It should be “run enough capacity for the named workload and failure conditions without paying for unexplained idle capacity.”
For example, one spare scheduling slot may be deliberate if it allows a critical replica to move during node maintenance. That headroom has an operational purpose. By contrast, a permanent 60% memory reservation caused by inflated requests deserves investigation.
Use Kubernetes Cost Optimization for the broader cost model. This guide owns how autoscaling decisions create or remove worker demand.
The decision framework separates workload pressure from cluster pressure
When something is “at capacity,” first identify which layer is actually constrained.
| Observation | Likely layer | First decision |
|---|---|---|
| CPU metric rises but replicas stay fixed | HPA | Validate metrics, requests, HPA conditions and max replicas |
| HPA adds replicas and all Pods schedule | Workload only | No node action needed yet |
| HPA adds replicas and some Pods are Pending | Cluster capacity | Check why scheduler cannot place them |
| Pending Pods fit a configured worker pool | Node autoscaling | Allow/add worker capacity within bounds |
| Pending Pods require a different node shape | Node-pool architecture | Add or change the appropriate pool |
| Workers remain underused after demand drops | Scale-down/consolidation | Check disruption, requests, minimum nodes and removable capacity |
| Workers repeatedly scale up and down | Feedback stability | Review requests, HPA thresholds, startup behavior and scale-down timing |
| Cost increases without traffic growth | Resource model | Compare requests, replicas, node packing and pool minimums |
For small teams, this framework is more useful than starting with a specific autoscaling tool. It gives each symptom an owner and prevents application scaling, scheduler placement, and infrastructure scaling from being debugged as one opaque system.