Browser demo

See the controller in motion — no install required.

The two charts below are rendered from real output of the offline simulator on the bundled 200 rps spike trace (baseline_spike_profile_dt15.csv). The same files you can reproduce locally with one command.

What the offline simulator sees

Both panels use the same input demand and the same scaling bounds (2–12 replicas, step ≤ 2). HPA is a CPU-target reactive baseline at 60%. MPC is a short-horizon (8-step) QP with normalized objective.

Demand and MPC short-horizon forecast over a 200 rps spike. Forecast peaks lower than the actual spike because the spike fires within a single step.
Demand jumps from 20 rps to 200 rps for 30 s. The MPC forecast catches the spike one step late — the inherent lag of any reactive forecaster.
Replica trajectory for HPA and MPC during the spike. Both ramp up; MPC holds replicas longer after the burst.
HPA drains aggressively after the burst; MPC holds extra capacity for the forecast horizon. In this offline view MPC costs more replicas with no SLO win — the readiness-lag advantage does not show up here.
HPA avg 3.46 replicas max 6, SLO miss 2 / 26 steps. MPC avg 4.77 replicas max 8, SLO miss 2 / 26 steps. Offline verdict MPC uses ~38% more replicas, same SLO.

Why the live cluster tells a different story

The offline simulator assumes new replicas are ready instantly. A real Kubernetes cluster does not. On the tracked spike pair, new Pods became Ready ~40 s after the scaling decision. HPA decides only when CPU already saturates, so its new capacity arrives after the latency damage is done. MPC scales on the forecast and gets there earlier.

Same load, same workload, same image. The number that flips:

HPA p95 ≈ 85 ms on the live 200 rps spike. MPC p95 ≈ 52 ms — about 38% lower. 30 s burst MPC still loses — the lag is longer than the event.

Sources: docs/RESULTS.md (evidence paths) and docs/LIMITATIONS.md (what the numbers do not prove).

30 seconds

Reproduce the figures above

python3 -m pip install -e analysis
mpc-offline-sim \
  --trace-csv analysis/mpc_autoscaler_analysis/data/traces/baseline_spike_profile_dt15.csv \
  --out-dir /tmp/demo

Outputs land in /tmp/demo/ as trajectory.csv, summary.json, and a PNG. The CSV behind this page is the same file; download it to compare:

trajectory.csv · summary.json

2 minutes

Run it on a live cluster

helm upgrade --install toy-load \
  toy-load/deploy/helm/toy-load \
  --namespace default --create-namespace

bash loadgen/scripts/run_hpa_experiment_incluster.sh spike
bash loadgen/scripts/run_mpc_experiment_incluster.sh spike

This is the path that produces the live numbers above. Full walkthrough: MPC vs HPA in 60 seconds.