Autoscaling triggers and metrics
coreintermediateAutoscaling is the automated version of the horizontal scaling decision covered in §13 (system-design.scaling.horizontal-vs-vertical) — instead of an engineer watching a dashboard and manually adding instances, a controller polls one or more metrics on a fixed interval and adds or removes instances when a metric crosses a threshold. The metric choice is the entire design problem: CPU and memory are the easiest to wire up (every host already reports them) but are only a proxy for the thing that actually matters — whether the service can keep up with demand. Request rate is closer to the real signal for a stateless web tier. Queue depth is closer still for a worker/consumer tier, because a worker can have low CPU while a queue backs up (the work is I/O-bound, or blocked waiting on a downstream dependency), which CPU-based scaling would completely miss. Custom metrics (e.g. in-flight requests per pod, p99 latency, a business metric like "carts pending checkout") exist because no built-in metric always reflects real load, and Kubernetes' Horizontal Pod Autoscaler explicitly supports external and custom metrics for exactly this reason.
Think of it as
Think of a restaurant deciding how many servers to have on shift. Scaling on CPU/memory alone is like deciding based on how tired the current servers look — a rough proxy, easy to observe, but disconnected from what customers actually experience. Scaling on request rate is like counting how many people walk in per minute. Scaling on queue depth is like counting how many parties are waiting for a table — the wait line is where a booked-solid but not-visibly-frantic restaurant reveals it is actually under strain. A custom metric is the manager's own judgment call, e.g. "the online order screen is backing up," when none of the generic counts capture the specific way this business gets overwhelmed.
What we're doing: Show why CPU-based scaling misses the bottleneck for a queue-consuming worker fleet.
- 9
- This is the blind spot from the metrics table: CPU stays flat while the real bottleneck (queue backlog) is actively growing.
- 15
- Queue depth reacts to the backlog directly, which is the signal that actually correlates with user-visible delay for this workload.
Why this works: CPU utilization is not wrong as a metric in general — it is wrong for this specific workload, where the bottleneck is I/O-bound waiting rather than compute. Picking a metric means picking one that actually tracks this workload's real constraint, not the easiest one to read.
Wiring the autoscaler to whichever metric is easiest to read, not the one that reflects the bottleneck
Wrong
Better
What you see: The queue backlog and end-to-end job latency both grow steadily during a downstream slowdown, while every dashboard showing CPU and memory looks calm — on-call has no autoscaling-related alert to look at because the metric it watches never left its target range.
Why: CPU utilization is the default example in almost every autoscaler tutorial, which makes it the path of least resistance regardless of whether it reflects the actual bottleneck for a given workload. A worker fleet blocked on downstream I/O is the textbook counter-example: the metric that is easiest to wire up is decoupled from the thing that is actually failing.
- Metric polled (start)
- → Compared to target when on each polling interval
- Compared to target
- → Replica count changed when desired replicas != current replicas
- Replica count changed (end)
Common autoscaling metrics and what they are actually proxies for
Remember: Autoscaling automates the horizontal-scaling decision from §13 by polling a metric and comparing it to a target; the metric choice is the whole design problem, not an implementation detail. CPU/memory are cheapest to wire up but are only proxies — queue depth fits worker/consumer tiers, request rate fits stateless web tiers, and a custom metric exists for whatever workload-specific bottleneck no built-in metric captures. A configured autoscaler is not proof the right metric was chosen.
See also: horizontal vs vertical · scaling tradeoffs

