Warmup Guide — Model Serving Platform
Zero-to-expert primer for Phase 09: the system around the model — serving patterns, latency distributions, dynamic batching, caching tiers, progressive delivery, and the cost economics of inference fleets.
Table of Contents
- Chapter 1: The Four Serving Patterns
- Chapter 2: Latency Is a Distribution
- Chapter 3: Dynamic Batching
- Chapter 4: Caching Tiers
- Chapter 5: Progressive Delivery — Shadow, Canary, Rollback
- Chapter 6: Autoscaling and Cost
- Chapter 7: The Serving Stack in Practice
- Lab Walkthrough Guidance
- Success Criteria
- Interview Q&A
- References
Chapter 1: The Four Serving Patterns
Choose the pattern before the framework — most "serving problems" are pattern mismatches:
| Pattern | Shape | Right when | Wrong when |
|---|---|---|---|
| Online (request/response) | sync API, ms budgets | user-facing decisions (ranking, fraud-at-checkout) | results aren't needed now |
| Batch scoring | score the whole table nightly | churn scores, embeddings refresh, anything pre-computable | inputs only exist at request time |
| Streaming | score events as they flow (Phase 02's consumer) | alerting, real-time features, near-real-time personalization | strict request/response coupling needed |
| Async / queue | accept → enqueue → callback/poll | expensive inferences (LLM generations, video), spiky load | sub-second UX requirements |
The senior move the JD calls "cost efficiency": precompute everything precomputable. A recommender that batch-scores candidates nightly and serves from a key-value lookup beats an online-scoring design by 10–100× in cost — and the hybrid (precomputed candidates + light online re-rank, Phase 06's architecture) is the industry default for exactly this reason.
Chapter 2: Latency Is a Distribution
- Report p50 / p95 / p99, never means: latency is right-skewed, and the mean is dominated by the tail you're trying to manage. SLOs bind on percentiles ("p99 < 100 ms") because users experience the tail.
- Tail amplification under fan-out: a request touching N services each with p99 = 100 ms has P(any one is slow) = 1 − 0.99ᴺ — at N = 10, ~9.6% of requests hit a 100 ms+ dependency. Microservice-heavy ML stacks (feature fetch + model + ranker + filters) live or die by this arithmetic; it's why feature-store reads (Phase 03) get single-digit-ms budgets.
- Measurement honesty (the Phase 07 model-accuracy lessons apply verbatim): warm up before measuring, percentiles need enough samples (p99 of 50 requests is noise), watch for coordinated omission (a load generator that waits for slow responses under-samples the tail — fixed-rate arrival schedules fix this; the lab's simulator uses arrival schedules for exactly this reason).
- The latency budget exercise: decompose the SLO end to end — network 5 ms + feature fetch 10 ms + inference 25 ms + post-processing 5 ms + headroom — and assign the budget per component. Components without budgets grow until the SLO breaks.
Chapter 3: Dynamic Batching
Why batching wins: every inference call pays fixed overhead (framework dispatch,
memory movement, kernel launches — and on GPUs, underutilized parallelism). A model
whose cost is c_fixed + n · c_item per call has per-item cost c_fixed/n + c_item
— batching amortizes the fixed term. On GPUs the effect is dramatic (the hardware
wants 10³+ parallel items — the Phase 07/08 model-accuracy bandwidth story); on
CPUs it's still real via vectorization (Phase 01's numpy lesson).
The mechanism (the lab's core): requests arrive asynchronously; a batcher queues them and flushes when either:
- the batch reaches
max_batch_size(the throughput knob), or - the oldest queued request has waited
max_wait(the latency knob).
The tradeoff, quantified: batching adds up to max_wait of queueing delay to
buy throughput. The frontier — p99 vs sustainable QPS as you sweep the knobs — is
the deliverable graph of both the lab and any real tuning exercise. Two regimes to
recognize: at low traffic, batches rarely fill → latency cost ≈ max_wait, little
throughput gain (consider batch size 1); at high traffic, batches fill instantly →
throughput gain ≈ full, queueing delay dominated by capacity, and max_wait barely
binds.
Setting max_wait: from the latency budget (Ch. 2) — if inference has a 40 ms
budget and the model takes 25 ms at your batch size, max_wait ≤ ~10 ms. It's a
derived number, not a vibe.
(LLM serving replaces this with continuous batching at iteration granularity — the llm-inference track Phase 09 and model-accuracy Phase 08 cover it; the queueing logic you build here is its foundation.)
Chapter 4: Caching Tiers
Work avoidance beats work optimization. The tiers, outermost first:
- Exact-match response cache: hash(model version, canonicalized input) → response. Hit rates are workload-dependent: high for popular-item recsys and repeated searches, ~zero for unique-per-user inputs. Always key on model version — serving stale predictions from the old model after a deploy is the classic cache incident.
- Feature cache / online store (Phase 03): the most load-bearing tier — it's why p99 feature reads stay single-digit ms.
- Embedding cache: user/item embeddings change slowly; cache with TTL matched to the refresh cadence; pairs with the ANN index (Phase 04).
- Intermediate caches (KV cache in LLMs, candidate lists in recsys): inside the model server itself.
The discipline for every tier: an explicit staleness contract (TTL chosen against the upstream change rate), an invalidation story (event-driven beats TTL where possible — Phase 02's streams), and hit-rate monitoring (a silently degraded cache looks exactly like a capacity problem).
Chapter 5: Progressive Delivery — Shadow, Canary, Rollback
Models are statistically validated, so deployment must be too:
- Shadow (mirroring): the new model receives a copy of live traffic; its outputs are logged, not served. Compares: output distributions, latency, error rate, divergence-vs-current on identical inputs. Zero user risk; catches engineering-level breakage and gross prediction shifts. Cannot measure outcome impact (nobody acted on its predictions) — that needs the canary/A-B.
- Canary: route a small fraction (1% → 5% → 25% → 100%) of live traffic;
monitor guardrails — error rate, latency, and the business guardrail
metrics — with statistical care (a 1% canary needs hours-to-days for significance
on subtle metrics; Phase 11's power math applies). The lab's
CanaryRouterimplements the decision: promote when healthy after the soak, auto-rollback on guardrail breach — rollback must be a pointer move (Phase 08's registry), not a build. - Blue/green: full parallel fleet, instant cutover/cutback — simpler, costlier, no gradual exposure.
- The composition that mature teams run: shadow first (engineering safety), then canary (outcome safety), then the A/B test (outcome measurement — Phase 11). Three different questions; three mechanisms.
Chapter 6: Autoscaling and Cost
- The GPU economics fact: an idle GPU costs the same as a busy one. Fleet cost ≈ replicas × instance price; replicas ≈ peak QPS / per-replica throughput — which is why batching (throughput ↑) and caching (QPS ↓) are cost levers first and latency levers second. Utilization below ~30% on a GPU fleet is a redesign signal (batch more, consolidate models, or move to CPU).
- Autoscaling signals, in order of usefulness for ML serving: queue depth / concurrency (leading, direct), latency (lagging — you scale after users already hurt), CPU/GPU utilization (misleading for memory-bound or bursty workloads), QPS (only with stable per-request cost).
- Cold starts: model loading (seconds–minutes for large models) makes scale-from-zero brutal — mitigations: min-replicas ≥ 1, model pre-warming, weights on fast local storage, smaller models (the whole model-accuracy track's reason for existing, from the platform side).
- Right-sizing heuristic (Extension B): compute per-replica sustainable QPS at the SLO from the measured frontier (Ch. 3), then fleet = peak-QPS / that, +30% headroom, then compare instance types by $/sustained-QPS — a one-afternoon exercise that routinely halves bills.
Chapter 7: The Serving Stack in Practice
Mapping the concepts to the tools you'll meet:
- Model servers: TorchServe / Triton Inference Server (dynamic batching built
in — the knobs are literally
max_batch_size/max_queue_delay, i.e., the lab), vLLM for LLMs (continuous batching), ONNX Runtime for portability. - The two-service shape: a thin business-logic API (auth, feature fetch, post-processing) in front of a model server — keeps GPU fleets dense and independently scalable from CPU logic.
- Interfaces: REST for compatibility, gRPC for internal hops (latency + streaming), batched endpoints for bulk.
- What "reliability" means here: timeouts + fallbacks at every hop (a ranking timeout falls back to popularity order, not an error page — degrade, don't fail), load shedding before collapse, and the observability of Phase 12 wired in from day one.
Lab Walkthrough Guidance
Lab 01 — Batching Server Simulator, suggested order:
percentile+LatencyRecorder— exact interpolation method per the docstring; the hand-computed test pins it.SimulatedClock+ request/arrival plumbing (provided) — read it; the simulator is discrete-event, so tests are deterministic and fast.DynamicBatcher.run— the flush policy. Get the two invariants right: no batch exceedsmax_batch_size; no request's batch-start exceeds its arrival +max_wait. Then latency accounting: completion = batch start + model time; request latency = completion − arrival.- The frontier experiment (
sweep) — run the provided workload across knob settings; the tests assert the qualitative shape (batching ≥5× throughput at bounded p99 cost vs batch-1). CanaryRouter— deterministic hash-based routing, per-arm metrics, the guardrail decision (promote/rollback/continue).
Success Criteria
You are ready for Phase 10 when you can, from memory:
- Match the four serving patterns to four product scenarios and name the precompute opportunity in each.
- Do the fan-out tail arithmetic and decompose an end-to-end latency budget.
- Explain both batching knobs, derive
max_waitfrom a budget, and describe both traffic regimes of the frontier. - Recite the caching tiers with each one's staleness contract.
- Distinguish shadow / canary / A/B by the question each answers.
- List autoscaling signals in usefulness order and the cold-start mitigations.
Interview Q&A
Q: Your p99 is 3× the SLO but p50 is fine. Where do you look?
Tail-specific causes, in order: queueing under bursts (look at queue-depth
percentiles — the mean hides the bursts), batching max_wait set too high for the
low-traffic regime, GC/checkpoint pauses in the server process, cache-miss path
(p50 = hits, p99 = misses — check hit rate), fan-out amplification (one slow
dependency), and noisy neighbors on shared infra. The p50/p99 split itself is the
diagnostic: the system is healthy on the common path and pathological on a minority
path — find which minority.
Q: When would you NOT add dynamic batching?
Low-traffic services (batches don't fill — you pay max_wait for nothing), models
where per-item cost dominates (no fixed term to amortize — check the measured cost
curve first), strict-latency paths whose budget can't fund any queueing, and
sequence models with high padding waste under heterogeneous lengths (bucket or use
continuous batching instead). The general answer: batching buys throughput with
latency — if you don't need the throughput or can't spend the latency, don't.
Q: Design the rollout for a new fraud model where false negatives cost real money. Shadow first — weeks, not days: compare score distributions and disagreement cases against the incumbent on identical traffic; have analysts review the high-disagreement set (fraud labels lag, so offline outcome comparison needs patience). Then a small canary with conservative guardrails — block rate, decline rate, manual-review queue depth — and asymmetric rollback bias (rollback on any doubt; the cost asymmetry demands it). Promote on canary parity plus the lagged label readout. And the org answer: pre-agree the guardrail thresholds and decision owner before the rollout starts — mid-rollout threshold negotiation is how bad models reach 100%.
References
- Triton Inference Server: dynamic batching docs — the lab's knobs, productionized
- Dean & Barroso, The Tail at Scale (CACM 2013) — the fan-out arithmetic and tail-tolerance patterns
- Tene, How NOT to Measure Latency — coordinated omission, canonically
- vLLM and the llm-inference track Phase 09 — continuous batching
- Kubernetes HPA + KEDA — queue-depth-driven autoscaling in practice
- Google SRE Book, ch. 21–22 — load shedding and handling overload