
When you send a prompt to an AI model (like ChatGPT or Claude) and it generates a response, that process is called inference โ the model is "inferring" an output from your input.
| Metric | What it means |
|---|---|
| TTFT (Time to First Token) | How long before you see the first word of the response |
| OTPS (Output Tokens Per Second) | How fast the model generates words after that |
| p95 | The 95th percentile โ meaning 95% of requests are faster than this number |
๐ก Simple analogy: Think of a restaurant. At lunch rush, even a great kitchen slows down. LLM inference has the same problem, but the "dishes" vary wildly in complexity.
"Can the system process my request at all?"
"How fast does the system respond?"
A system can be:
๐ก Key insight: Latency problems can become availability problems. If a server gets too slow, it effectively becomes unavailable.
| Property | CPU Systems | GPU Systems |
|---|---|---|
| Reliability | Very stable | Less stable |
| Cost | Moderate | Very expensive |
| Failure impact | Usually isolated | Can cascade |
All-to-all communication:
Single-rack topology:
| Classic Fix | Why It Fails for GPUs |
|---|---|
| Multi-AZ (backup data centers) | Requires idle backup GPUs โ extremely expensive |
| Overprovisioning | GPU supply is constrained; not practical |
๐ก Analogy: Imagine a surgical team where every member must work in perfect sync. If one surgeon leaves mid-operation, the whole procedure is at risk โ you can't just "add a backup surgeon in another room."
Unlike a web server (where most requests take similar time), LLM requests vary enormously in cost:
More requests on one server โ Higher throughput (cost efficient)
โ But each request gets slower (higher latency)
๐ก Analogy: A highway with more cars moves more total people, but each car moves slower. LLM servers face the same tradeoff.
How do you compare the "cost" of:
You need a single unit of measurement.
A model unit is an abstraction that estimates how much of a server's capacity a request will consume.
Model Units = ฮฑ ร (input tokens) + ฮฒ ร (output tokens) + ฮณ ร (image tokens)
| Without Model Units | With Model Units |
|---|---|
| "I have 50 requests queued" | "I'm at 87% capacity" |
| Can't distinguish short vs. long requests | Accurately reflects true load |
| Scaling decisions are guesswork | Scaling decisions are data-driven |
๐ก Analogy: Instead of measuring a restaurant's busyness by "number of customers," you measure it by "total cooking time needed." A table ordering 10 courses is very different from a table ordering coffee.
When many servers exist, a load balancer decides which server handles each incoming request.
Dicer routes based on model unit utilization instead of request count:
Traditional: "Server A has 10 requests, Server B has 15 โ send to A"
Dicer: "Server A is at 90% model unit capacity โ send to B"
๐ก Analogy: Instead of sending customers to whichever checkout line is shortest, you send them to the cashier who already knows their loyalty account โ faster for everyone.
Automatically adding or removing servers based on current demand.
Naive signal: "I have 100 pending requests โ scale up"
Problem: 100 short requests โ 100 long requests
CPU and memory metrics are also uncorrelated with actual GPU utilization for LLMs.
If model unit utilization > threshold โ scale UP (add servers)
If model unit utilization < threshold โ scale DOWN (remove servers)
๐ก Analogy: A smart taxi dispatch system that counts "passenger-miles needed" rather than just "number of passengers" โ a trip across town counts more than a trip around the block.
A server stops responding but doesn't crash or throw an error. It just... freezes.
Common causes:
Periodically send a minimal test request to each server
If no real requests have completed recently AND the test fails โ restart the server
This works regardless of which inference engine is being used.
Problem: Under heavy load, health checks themselves time out โ system thinks healthy servers are broken โ kills them โ cascading failure
Solution: Give health check requests the highest scheduling priority
๐ก Analogy: A hospital's "code blue" alarm system. If the alarm itself gets stuck in a queue, you have a bigger problem. It must always have priority access.
When large batches of image requests arrived, error rates spiked โ but the GPU was fine.
Root cause: Image processing is CPU-intensive, not just GPU-intensive:
Image request arrives
โ CPU starts processing image (slow)
โ Event loop gets blocked
โ No other requests can be processed
โ Timeouts and errors spike
๐ก Analogy: A factory assembly line where the bottleneck isn't the main machine (GPU) but the person unpacking boxes (CPU image processing). Speeding up the unpacking unlocks the whole line.
User Request
โ
[Load Balancer - Dicer]
Routes based on Model Unit utilization
Sticky sessions for cache efficiency
โ
[Autoscaler]
Adds/removes servers based on Model Unit utilization
Saves 80%+ GPU costs vs. static provisioning
โ
[Inference Server]
Health checks detect silent hangs
Prioritized health checks prevent false restarts
Optimized image processing prevents CPU bottlenecks
โ
Response
| Problem | Solution |
|---|---|
| Variable request costs | Model Units as a common currency |
| Poor routing decisions | Dicer with model-unit-aware routing |
| Wasteful scaling | Model-unit-based autoscaling |
| Silent server hangs | Prioritized black-box health checks |
| CPU bottlenecks in multimodal | Library optimization + thread configuration |
๐ฏ The big takeaway: Reliable LLM inference at scale requires rethinking every assumption from traditional distributed systems โ from how you measure load, to how you route requests, to how you detect failures โ because LLM workloads are fundamentally different from web traffic.