Problem Context

"The LLM is slow" isn't a metric. There are at least four latencies that matter for an LLM-backed feature, and they degrade for different reasons. Confusing them โ€” or aggregating them into a single "p95 latency" โ€” hides every interesting failure mode.

๐Ÿค” Sound familiar?
  • Your "LLM latency" chart is a single line and you can't explain spikes
  • Users complain it "feels slow" but your p95 is fine
  • You can't tell whether to optimise the model, the prompt, the network, or the streaming pipeline

The Four Latencies

  • TTFT (time-to-first-token) โ€” from request sent to first token received. Dominates perceived responsiveness.
  • TPS / TPOT (tokens-per-second / time-per-output-token) โ€” generation throughput once streaming starts.
  • Total generation time โ€” TTFT + (output_tokens ร— TPOT). The number your billing-ops team cares about.
  • End-to-end (E2E) โ€” what the user sees: includes auth, retrieval, guardrails, post-processing, network back to client.

flowchart LR
    U[User clicks] -->|t0| API[API gateway]
    API -->|auth| RAG[Retrieval]
    RAG -->|t1| LLM[LLM provider]
    LLM -->|t2: first token| STR[Stream to client]
    STR -->|t3: last token| POST[Guardrails + format]
    POST -->|t4| U
      

TTFT = t2 - t1. TPOT = (t3 - t2) / output_tokens. E2E = t4 - t0.

What Drives Each

  • TTFT โ€” input length (KV cache prefill), provider load, region, model size, queueing.
  • TPOT โ€” model size, output length tier (some providers throttle long outputs), provider capacity.
  • Total generation โ€” output length ร— TPOT; cut output length, cut total.
  • E2E โ€” everything above + your own retrieval/guardrails/post-processing overhead.

The Right Percentiles

Always look at p50, p95, p99per metric. P50 tells you the "feels like", p95 catches creeping regressions, p99 catches the long-tail nightmares (cold model loads, regional failover). Mean is a lie for LLM latency distributions โ€” they are heavy-tailed.

Streaming Changes Everything

With streaming, the user starts reading as the tokens arrive. The metric you optimise is no longer total generation; it is TTFT plus sustained TPOT > ~30 tokens/sec (the comfortable reading speed). A model that finishes in 4 s total but starts in 1.8 s feels worse than one that finishes in 6 s but starts in 0.4 s.

The Levers

  • Cut input tokens โ€” shorter context = faster prefill = lower TTFT. Often the cheapest win.
  • Prompt caching โ€” cached prefixes prefill far faster; TTFT can drop 40โ€“60%.
  • Smaller / distilled model โ€” gpt-4o-mini vs gpt-4o: 2โ€“4ร— faster TPOT. Use task-specific routing.
  • Speculative decoding / draft models โ€” provider-side; available on some hosted models. Free TPOT win when enabled.
  • Provisioned throughput (Azure PTU, Anthropic dedicated) โ€” eliminates queueing variance for steady workloads.
  • Region pinning โ€” same continent as your app server cuts 50โ€“200 ms of network alone.

Measuring TTFT in Streaming Code

const t1 = performance.now();
const stream = await client.chat.completions.create({ model, messages, stream: true });

let ttft = 0, tokens = 0, t2 = 0;
for await (const chunk of stream) {
  if (!t2 && chunk.choices[0]?.delta?.content) {
    t2 = performance.now();
    ttft = t2 - t1;
  }
  tokens += 1;
}
const t3 = performance.now();
metrics.histogram('llm.ttft.ms', ttft, { model });
metrics.histogram('llm.tpot.ms', (t3 - t2) / tokens, { model });

Failure Modes

  • Conflating E2E with model latency โ€” your "LLM is slow" alert fires because retrieval got slow.
  • Aggregating across models โ€” gpt-4o and gpt-4o-mini in one chart hides everything useful.
  • No TTFT metric at all โ€” streaming UX optimisations are invisible.
  • Sampling out the tail โ€” if you only capture 1% you miss p99. Use tail-based sampling that prioritises slow requests.

Production Checklist

  • Four metrics, not one: TTFT, TPOT, total generation, E2E.
  • p50/p95/p99 per metric per model per endpoint.
  • SLOs phrased in TTFT and TPOT, not just total โ€” they map to UX.
  • Tail-biased sampling so the slow requests are over-represented in your traces.

Key Takeaways

  • TTFT is the perceived-latency king for streaming apps; TPOT keeps the perception going.
  • The right intervention depends on which of the four latencies is the bottleneck โ€” diagnose before you optimise.
  • Prompt caching + smaller-model routing + region pinning are the three highest-ROI levers for most teams.