agents/prod
08
Infrastructure · Chapter 8

Deploying, autoscaling & durable execution

Serving one replica is solved. The hard part is running many under bursty, long-running, failure-prone agent traffic — where the usual Kubernetes reflexes are not just suboptimal, they're actively wrong. Here's what breaks and how production teams fix it.

1 · Why standard autoscaling is blind

Kubernetes' default HPA scales on CPU. For LLM serving that fails: the GPU does the compute (CPU stays near-idle) and vLLM pre-allocates the KV cache at startup (GPU memory looks constant). A pod handling 50 concurrent requests can sit at 5–8% CPU while its GPU is at 95% and latency hits 30s — HPA sees "healthy" and never scales.

CPU (HPA watches)7%
GPU (actual load)95%
Queue backing up
The autoscaler watches the one meter that stays flat. The GPU is on fire and the queue is growing — but CPU says "idle," so nothing scales.

2 · Scale on queue depth (KEDA)

The fix: scale on application metrics with KEDA, not CPU with HPA. The best signal is queue depth (vllm:num_requests_waiting). Push traffic up and watch the two approaches diverge — CPU-based stays stuck at one replica while requests pile up:

Interactive · CPU-HPA vs. queue-depth autoscaling
incoming load:
CPU HPA
KEDA (queue)

Recommended queue thresholds scale with model size: 10–20 for <10B, 5–10 for 10–70B, 2–5 for >70B. KEDA also enables scale-to-zero (cost-effective only below ~5–10 sustained RPS).

3 · The cold-start problem

A vLLM pod can take 2–5 minutes to become ready — and the dominant cost is usually pulling the container image (4–6 min uncached), not loading weights. So pre-pull images, put weights on a fast PVC, and keep scale-down cooldowns ≥300s to avoid thrash.

where a cold start's time actually goes
image pull (4–6 min)
weights
Pre-pulling the image is the single biggest cold-start win — the weights aren't the bottleneck.

4 · Durable execution — surviving crashes

Agents run minutes to hours and make expensive, side-effecting calls. A plain loop loses everything on a crash. Durable execution (Temporal, Restate) journals every completed step, so after a crash it replays and skips completed steps — exactly-once semantics. Trigger a crash and watch it resume:

Interactive · crash & replay
Run a few steps, then Crash. Without durability you'd restart from zero (re-paying every LLM call). With it, completed steps replay from the journal instantly and execution resumes at the failure point.

5 · Reliability patterns & compounding error

Multi-step reliability multiplies: independent steps at r each give rn overall. That's why you verify per step and add retries (backoff + jitter), fallbacks, and circuit breakers. See how fast it decays:

Interactive · compounding error calculator
per-step reliability:   steps:
Carry into Chapter 9

Scaling assumes the code your agent runs is safe to run. It usually isn't — the model can be manipulated into running attacker code. Next: isolation — how to run untrusted, model-generated code without handing over your infrastructure.