Your AI feature's median response time tells you almost nothing about whether users are frustrated. P99 latency — the response time that your slowest 1% of requests exceed — is what determines churn, because users remember their worst experience with a product far more vividly than their typical one. Streaming can convert a slow total completion into a fast-feeling one by shortening time-to-first-token.
Quick answer: Measure
p50,p95, andp99separately, track time-to-first-token apart from total completion time, and use streaming to attack perceived latency even when you can't reduce total compute time.
Why Median Latency Is the Wrong Metric for AI Products
The median (p50) describes the typical request, but users don't judge products by typical experiences — they judge them by the worst thing that recently happened to them. A feature that feels "fast" 95% of the time and unbearably slow 5% of the time will still generate support tickets, negative reviews, and quiet abandonment.
This is worse in AI products than in traditional software because LLM inference has much higher variance than a database read or a cached API call. Token generation speed fluctuates with model load, prompt length, context window size, and even which GPU shard your request landed on. A traditional web request might vary between 100ms and 300ms. An LLM completion can vary between 800ms and 14 seconds for the same prompt, run twice, five minutes apart.
Nielsen Norman Group's long-standing research on response-time thresholds still holds the core insight even in the LLM era: users perceive interfaces categorically, not continuously. Something under roughly 1 second feels instantaneous; several seconds feels like a "wait" that breaks flow; beyond about 10 seconds, attention disengages entirely unless there's a strong progress signal. Averages smear over these thresholds. A single p50 number can sit comfortably under 1 second while a meaningful share of real requests blow past the 10-second disengagement line.
The Asymmetry of Bad Experiences
Behavioral research on the peak-end rule, most associated with Daniel Kahneman's work on experienced versus remembered utility, shows that people judge an experience by its most intense moment and its ending — not by the average of every moment within it. Applied to AI UX: one 12-second stall in an otherwise-fast session can dominate a user's memory of the entire feature, even if the other nineteen interactions that day were instant.
This is why teams that only watch dashboards built around mean or median latency consistently underestimate churn risk. The pain is concentrated in the tail, and the tail is exactly what a mean erases.
What P95 and P99 Actually Measure, and Why They Diverge
p95 and p99 are percentile cutoffs: p95 is the latency that 95% of requests beat, and p99 is the latency that 99% of requests beat. The gap between them, and between either and the median, reveals whether your system has a long, unpredictable tail — the single biggest predictor of perceived unreliability in an AI feature.
A system with p50 = 1.2s and p99 = 1.8s is well-behaved: predictable, tight, low-variance. A system with p50 = 1.2s and p99 = 11s has a serious tail problem, even though the "typical" experience looks identical on paper. Only percentile reporting exposes this difference.
| Metric | What it tells you | What it hides |
|---|---|---|
p50 (median) | The typical request experience | Everything about worst-case behavior |
p95 | 1 in 20 requests are slower than this | The most extreme 1% of failures |
p99 | 1 in 100 requests are slower than this | Whether p99 is 2x or 20x the median |
p99.9 | 1 in 1,000 requests are slower than this | Rare but often catastrophic outliers (retries, timeouts) |
| max | The single worst observed request | Nothing, but it's noisy and easily skewed by one-off anomalies |
Google's engineering literature on service-level objectives — most notably the publicly available Site Reliability Engineering book — popularized the idea that you should set SLOs on percentiles, not averages, precisely because averages let you "pass" while a meaningful slice of your users are having a bad time. That lesson maps directly onto LLM-backed features: an eval suite that only reports mean latency is an SLO built to hide the truth from itself.
Where the Tail Comes From in LLM Systems
Tail latency in AI products typically has a small number of recurring causes, and diagnosing which one dominates changes your fix entirely.
- Cold starts and model loading — a request hits an unwarmed instance or a model that just got swapped in.
- Context length variance — longer prompts and larger retrieved context take longer to process before the first token, independent of output length.
- Provider-side queuing — shared inference infrastructure means your p99 is partly someone else's traffic spike.
- Retry cascades — a timeout triggers a retry, which doubles the effective latency for that user and disproportionately inflates
p99. - Downstream tool calls — agentic flows that chain a retrieval step, a function call, and a generation step compound each component's tail into one much longer tail.
Because these causes are structurally different, a single "reduce latency" backlog item is usually too vague to act on. You need per-cause instrumentation, which is the same discipline covered in a complete guide to LLMOps observability — without that instrumentation layer, percentile numbers exist but nobody can explain why they moved.
Time-to-First-Token vs. Total Completion Time
Time-to-first-token (TTFT) measures how long a user waits before anything appears on screen; total completion time measures how long until the full response is finished generating. They are different metrics driven by different bottlenecks, and conflating them causes teams to optimize the wrong half of the pipeline.
TTFT is dominated by prompt processing: tokenizing the input, running it through the model's context window, and beginning generation. It's sensitive to prompt length, retrieved context size, and queuing delay. Total completion time adds the entire generation phase on top — which scales roughly linearly with output length and generation speed (tokens per second).
A feature can have an excellent TTFT and a terrible total completion time, or the reverse, and each produces a different failure mode:
- Bad TTFT, fine total time: users perceive the app as unresponsive or broken before anything happens; they often refresh, retry, or abandon before the (perfectly fine) output ever arrives.
- Fine TTFT, bad total time: users see progress start immediately, stay engaged, and tolerate a longer overall wait because they can see it working.
This is the entire argument for measuring the two separately, and it's also the entire argument for streaming.
Why This Distinction Changes Your Optimization Priorities
If your dashboards only report a single "response time" number, you cannot tell which of these two situations you're in, and you'll optimize blindly. A team chasing a bad aggregate number might spend a quarter optimizing token generation speed when the real problem is a bloated system prompt inflating TTFT. Splitting the metric is a five-minute instrumentation change that redirects months of engineering effort correctly.
How Streaming Trades Total Time for Perceived Speed
Streaming doesn't make the model faster — total completion time is often unchanged or even slightly worse due to network overhead. What it does is deliver the first tokens to the screen almost immediately, which collapses TTFT toward near-zero and gives users continuous evidence that the system is working, which is what perceived speed actually measures.
This works because of a well-documented gap between objective duration and perceived duration in waiting experiences. Research on queueing psychology — the foundational work here traces back to David Maister's writing on the psychology of waiting lines, later applied extensively in UX contexts — consistently finds that occupied, informative waits feel shorter than unoccupied, silent ones, even when their actual duration is identical or longer.
A blank screen for 4 seconds followed by an instant full response feels worse to most users than tokens trickling in continuously for 6 seconds. The second experience is objectively slower and subjectively faster.
A Worked Example: Two Models, Identical Medians, Different Tails
Consider two models being evaluated for the same summarization feature. Both report a p50 total completion time of 2.1 seconds in your evals dashboard — on that number alone, they look interchangeable.
| Metric | Model A | Model B |
|---|---|---|
| p50 total completion time | 2.1s | 2.1s |
| p95 total completion time | 2.6s | 6.8s |
| p99 total completion time | 3.0s | 14.2s |
| p50 TTFT | 1.8s | 0.3s |
| p99 TTFT | 2.4s | 0.6s |
| Streaming supported | No | Yes |
Model A is consistent but slow to show anything — nearly the entire response arrives at once near the end of the wait, with a tight tail. Model B has a wide, ugly tail on total completion time, but its TTFT is fast and stable even at p99, and it streams.
If you only looked at p50, you'd call this a coin flip. In practice, users experience Model B as dramatically faster in the vast majority of sessions, because they see output starting in well under a second and stay engaged through the (occasionally long) remainder. Model A's users stare at a blank state for nearly two seconds every single time, with no signal that anything is happening — and on the (rare, high-impact) occasions their request lands in a slow shard, they get the worst of both worlds: silence, followed by more silence.
This is why a p50-only eval report can actively mislead a model-selection decision. The distinction between the two models only becomes visible once you split TTFT from total time and look at the tail, not the average — the exact blind spot an eval-case pipeline built from real production failures is designed to catch before it reaches a shipped decision.
Building an Observability Practice Around Tail Latency
Tail latency has to be a first-class, always-visible metric, not something you check reactively after a complaint. That means dashboards built around percentiles by default, alerting thresholds set on p95/p99 rather than averages, and TTFT tracked as a metric distinct from total completion time in every release.
Practical steps for an AI PM setting this up with an engineering counterpart:
- Instrument TTFT and total completion time as separate events, not derived after the fact from logs — derived math after the fact is fragile and easy to get subtly wrong.
- Set SLOs on
p95andp99, notp50— pick thresholds tied to the disengagement points from response-time research (roughly 1s, 10s) rather than arbitrary round numbers. - Segment tail latency by prompt length, context size, and route — an aggregate
p99across wildly different request shapes hides which shape is actually the problem. - Watch for retry-driven tail inflation — a spike in
p99correlated with a spike in retry rate usually means a timeout threshold, not a model problem. - Review the tail weekly, not just after incidents — a slow creep in
p99over several weeks is a leading indicator, and the kind of signal worth surfacing in the three dashboards worth building on day one of any AI product.
None of this replaces good judgment about where in the user's actual flow a slow response does the most damage — a 3-second delay during idle browsing and a 3-second delay mid-task carry completely different emotional weight, and percentile dashboards alone don't show you that difference.
Where Prodinja Fits
This is exactly the gap Prodinja's Customer Journey tool is built to help you close: its emotion curve lets you map a user's flow step by step and mark where anticipation is highest, so you can see precisely which point in the journey a latency spike would do the most damage if it landed there. It doesn't run your latency telemetry for you — it's designed to help you reason about where in the experience the tail hurts most, so your engineering priorities for shaving p99 line up with the moments users are most emotionally invested in, not just the moments that are technically easiest to fix.
Pairing that journey-level view with the kind of structured latency data described in a JTBD-driven approach to understanding what users actually need done and a full walkthrough of mapping the customer journey end to end gives you both the emotional context and the technical detail — because a p99 spike during an urgent, high-stakes task is a very different product problem than the same spike during idle exploration.
Key Takeaways
- Median latency systematically understates user pain — the peak-end rule means one bad tail experience can define a user's memory of an entire feature.
- Report
p95andp99alongsidep50, and set alerting thresholds on percentiles, not averages, following the SRE practice of SLOs built on tail behavior. - Separate time-to-first-token from total completion time — they're driven by different bottlenecks and require different fixes.
- Streaming doesn't reduce total compute time; it collapses perceived wait by giving users continuous evidence of progress, per the psychology of occupied versus unoccupied waits.
- Two models with identical medians can produce opposite user experiences once you compare their tails and TTFT — always evaluate both before a model-selection decision.
- Segment tail latency by prompt length, context size, and route so a single aggregate
p99doesn't hide which request shape is actually the problem. - Map latency risk onto the emotional stakes of the moment, not just the technical difficulty of fixing it, using a journey-level view of where users are most invested.
Frequently Asked Questions
What is p99 latency in AI applications?
P99 latency is the response time that 99% of requests complete faster than — meaning the slowest 1% of requests are worse than this number. In AI features, it's the single best proxy for how bad a user's worst realistic experience will be, because LLM inference variance makes that tail unusually long compared to traditional software.
Why does streaming reduce perceived latency without reducing total latency?
Streaming delivers the first tokens almost immediately, which collapses time-to-first-token toward near-zero and gives users continuous visual evidence the system is working. Total completion time is often unchanged or slightly higher due to network overhead, but occupied, informative waits are consistently perceived as shorter than silent ones of equal or even longer duration.
What's the difference between time-to-first-token and total completion time?
Time-to-first-token (TTFT) measures the wait before any output appears and is driven mostly by prompt processing and queuing; total completion time measures the full response duration and scales with output length and generation speed. A feature can score well on one and poorly on the other, so they need to be tracked and optimized separately.
How do I set a latency SLO for an LLM feature?
Set your service-level objective on p95 or p99, not the median, using response-time research thresholds (roughly 1 second for "instant," roughly 10 seconds for disengagement) as anchors rather than arbitrary round numbers. Segment the SLO by request shape — prompt length, context size, route — since an aggregate percentile across very different request types hides which shape is actually failing.
Why do two models with the same median latency feel so different to users?
Because the median only describes the typical request; it says nothing about the width of the tail or how quickly the first token appears. A model with a fast, stable time-to-first-token and streaming support can feel dramatically faster than one with an identical median but a blank-screen wait and a long, unpredictable tail at p95/p99.