Skip to main content

Latency Intuition

In one line: Users care about time to first token far more than total time — and streaming makes a slow model feel fast as long as the first token shows up quickly.

In plain English

There are two clocks on every AI response: how long until the first word appears (time to first token, or TTFT), and how long until the whole answer is done. Users judge almost entirely by the first clock. A reply that starts appearing in a fraction of a second feels fast even if it streams for several more seconds, while the same answer dumped all at once after a long pause feels broken. That's why streaming is the single biggest UX win — and why this page measures everything in TTFT first.

1. The two latencies​

MetricWhat it measuresWhat users feel
TTFT (Time to First Token)From request sent → first token rendered"How fast did this start?"
Total timeFrom request sent → last token rendered"How long until I can act?"
Inter-token timeSteady-state stream rate"Is it stalling?"

For a streaming chat response, TTFT dominates user perception. A 200ms TTFT followed by 4 seconds of streaming feels instant. A 4-second TTFT followed by a single dump feels broken — even if total time is identical.

2. The user-perception thresholds​

ThresholdWhat it means
<100msFeels instant
100–300msFeels responsive
300ms–1sNoticeable lag
1–3s"Is this thing working?"
>3sMany users abandon

For TTFT in a chat UI, the target is <500ms. For non-streaming responses (small structured outputs), the target is total time <1s.

3. What goes into LLM latency​

UserYour appProvider APIModelsubmit request (T0)HTTP POST~50ms network + TLSqueue + start inference~50-500ms queue + first-token computefirst tokenSSE chunkrender first token (T1) TTFT= T1 - T0next tokenSSE chunkappendlast token (T2) Total = T2 -T0

The breakdown for a typical workhorse call:

  • Network + TLS: ~50ms (or 200ms if you're far from the provider).
  • API queueing: 0–200ms depending on load.
  • First-token compute: 100–500ms (varies by model, prompt length).
  • Total TTFT: typically 300ms–1.5s.
  • Per-token streaming rate: typically 30–100 tok/s on modern providers; up to 500+ tok/s on Groq for open-weights models.

4. The optimizations, ranked by impact​

1. Streaming (often a 5–10x perceived speedup)​

The single biggest UX win. Non-streaming: user stares at a blinking cursor for 3s, then a wall of text. Streaming: tokens appear in 300ms, user starts reading immediately.

If your UI shows model output to a human, stream. Almost always.

2. Smaller / faster models (often 2–5x TTFT improvement)​

Cheap tier models are typically 2–3x faster TTFT than workhorse. If you can drop a tier without losing quality, you gain latency for free.

3. Groq / hosted-open-weights (often 5–10x speedup for open models)​

Groq runs Llama / Mistral models on custom hardware at ~500 tok/s — sometimes 10x faster than the same models on standard inference. For chat UIs where TTFT matters, this is a free win if your evals pass on these models.

4. Shorter prompts (10–30% TTFT improvement)​

First-token compute scales with input size. A 10k-token prompt's TTFT is meaningfully slower than a 1k-token prompt's, especially on workhorse+ tiers.

Cache stable prefixes (Anthropic prompt caching, OpenAI cached input). Cached input doesn't just save cost — it also speeds up TTFT.

5. Shorter outputs (linear in output length)​

Total time is dominated by output length once streaming starts. "Reply concisely" + a tight max_tokens reduces total time directly.

6. Provider geographic routing (50–200ms)​

If your users are in EU and your provider region is US, every call adds 100–200ms round-trip. Some providers offer regional endpoints; AI gateways (Cloudflare AI Gateway) can route to the closest region.

7. Avoiding agent loops on user-facing requests​

An agent that takes 5 iterations is 5x the latency. Where possible, do prep work asynchronously (precompute embeddings, pre-fetch context) and put only the final "answer" call in the user's critical path.

8. Pre-warming / connection pooling​

The first request to a new connection pays TCP+TLS handshake. Keep connections alive. Most SDKs do this automatically; verify.

5. The streaming UX patterns​

Streaming isn't just "show tokens as they arrive." Production patterns:

Show a "thinking" state immediately​

The 200ms–1.5s TTFT window is the killer. Show something immediately — a typing-dots indicator, a skeleton, anything — so the user knows the system received the input.

Progressive disclosure​

For structured outputs, stream parsed chunks as they complete: show the user the category field as soon as it parses, before the rest finishes.

Don't block the input while streaming​

Many chat UIs disable the input during generation. For long responses, users want to type their next message. Show the streaming response in a "currently generating" state but keep the input live.

The stop button (re-emphasis from Stage 2)​

A working stop button changes "this is slow" to "I'm in control." Critical for trust.

Inter-token-time alerts​

If the stream stalls for >2 seconds mid-generation, show a visible "still working..." indicator. Users assume "stalled stream" = "broken app" unless told otherwise.

6. Latency budgets by feature shape​

Rough targets for shipping-quality:

FeatureTTFT targetTotal time targetNotes
Chat reply<500ms<8sStreaming essential
Autocomplete<100ms<300msCheap-tier + Groq
Structured extraction (background)n/a<2sNo user wait
Search reranking<200ms<500msCheap-tier or specialized reranker
Voice response (TTS)<300ms TTFT<2sVoice is unforgiving
Agent step<1s<30s per runMulti-step; total = sum of steps
Document summarization<2s<30sAsync; users tolerate a "processing..." UI

Miss a budget and the feature feels broken even if it's working correctly.

7. Measuring latency​

Track in your observability layer (Stage 7):

SELECT feature, model,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ttft_ms) AS p50_ttft,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY ttft_ms) AS p95_ttft,
PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY ttft_ms) AS p99_ttft,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY total_ms) AS p95_total
FROM llm_calls WHERE ts > now() - interval '24h'
GROUP BY feature, model
ORDER BY p95_ttft DESC;

Alert when p95 TTFT exceeds your budget for a sustained window (say 10 minutes).

8. The provider/model latency variance​

Latency varies by provider AND model AND time of day:

  • OpenAI / Anthropic: typically 200–500ms TTFT for workhorse; can spike to 2–5s under load.
  • Groq: extremely fast (~100ms TTFT) for open-weights; less stable, narrower model set.
  • Google Gemini: middle of the pack, often very fast on Flash variants.
  • Self-hosted (vLLM, Ollama): depends entirely on your hardware; can be sub-100ms or multi-second.

Time-of-day matters: peak US business hours show 30–100% higher latency at major providers. Budget for the p95, not the median.

9. When latency vs quality forces a trade​

Sometimes the model that passes evals is too slow. Options:

  • Two-tier: fast cheap-tier for the user-visible response, workhorse for the deeper async work after.
  • Speculative: start generating with a faster model; if it's clearly wrong, retry with the slower model.
  • Streaming + abort: start the fast model; if it pauses (suggesting it's struggling), abort and switch.
  • Cached precomputation: do the slow analysis ahead of time on common queries; serve from cache.

Latency is a UX decision, not a model decision. Architect around it.

Common mistakes​

Where people commonly trip up
  • Optimizing total time, ignoring TTFT. Users feel TTFT. A 200ms TTFT with slow streaming beats a 4s TTFT with fast streaming, every time, on identical total times.
  • Not streaming. "I'll add streaming later." Now is later. The single biggest UX improvement for chat UIs.
  • Long prompts everywhere. First-token compute scales with input. A bloated system prompt costs latency AND cost. Cache prefixes.
  • Synchronous agent loops in user-facing requests. Multi-step agents in the critical path are the slowest UX. Push prep work async.
  • No latency dashboards. "It feels fast on my machine" is not data. P95 TTFT broken down by feature is data.
  • Treating "the API is slow" as the model being slow. Often it's your network, region, prompt length, or queue. Decompose before fixing.
🤔 Quick checkQuick check

→ Next: Safety mindset — prompt injection, data exfiltration, the defense-in-depth that actually works.