Skip to main content

LLM Tail Latency: Why Your P99 Is a Disaster When P50 Looks Fine

· 10 min read
Tian Pan
Software Engineer

Your LLM API returns a median (P50) latency of 800 milliseconds. Your dashboard is green. Your SLAs say "under two seconds." Then a user files a support ticket: "it just spins for thirty seconds and then gives up." You check the logs and see a P99 of 28 seconds.

That gap — a 35x ratio between median and tail latency — is not a fluke. It is a structural property of how LLMs work, and it will not go away by tuning your timeouts.

The core issue is that LLMs violate the foundational assumption behind almost every API monitoring practice you have inherited from conventional software: that response time is roughly a function of input size. For a database query, a REST endpoint, or a search index call, inputs with similar payloads produce outputs in a predictable range. For an LLM, output length is a random variable with a heavy-tailed distribution, and latency scales linearly with that random variable. Every tool for reasoning about "typical" API latency is built on an assumption that simply does not hold.

Why LLM Latency Is Structurally Heavy-Tailed

In a conventional decode batch, the GPU processes all requests in parallel up to the maximum output length among batch members. Every other request in the batch waits for the longest one to finish. If one request generates 4,000 tokens and nine others generate 200 each, all ten pay close to the 4,000-token decode cost.

Research measuring output length distributions across coding, summarization, and QA tasks finds max-to-median ratios of 2x to 4x: a Llama model on coding tasks produces outputs up to 3.27x its own median length; on long-form tasks, that ratio reaches 4x. That ratio translates directly into a P99/P50 E2E latency ratio in non-streaming settings — and the batch amplification effect makes it worse than the per-request ratio suggests.

Queuing theory formalizes why this is so damaging. In a system where service time has high variance, mean queueing delay scales with the second moment of service time — not the mean. A small number of runaway long-output requests inflates E[S²] dramatically, causing elevated queueing delays for every other request in the system. The batch cannot be reordered to fix this because preemption mid-generation is expensive.

Three additional factors compound the base distribution effect:

Context length heterogeneity. Time to first token (TTFT) grows roughly linearly with uncached prompt tokens. A request with a 32,000-token context can have a TTFT 100x longer than one with a 320-token context. In real production workloads, conversation history creates a heavy-tailed distribution of context lengths even when the application itself looks uniform.

Multi-step chain-of-thought and agentic calls. Extended reasoning multiplies output token count per step. An agentic workflow with five sequential LLM calls compounds each step's heavy tail via convolution: the end-to-end tail grows faster than any individual step's tail. What looks like a 3x output-length ratio per call becomes a 15x+ E2E latency ratio across a five-step chain.

Prefill/decode phase interference. Prefill (processing input tokens) is compute-bound and can saturate the GPU. Decode (generating one token per step) is memory-bandwidth-bound. When a long prefill arrives while decode is in progress, it preempts the ongoing batch. Measurements on production systems show naive hybrid batching causes up to a 28x increase in inter-token latency versus decode-only batches. vLLM P99 inter-token latency reached 1.76 seconds on internal workloads — compared to typical median inter-token latency in the tens of milliseconds.

The Techniques That Fix P50 and Break P99

The natural response to latency problems is to reach for the standard infrastructure playbook. For LLMs, several standard moves make tail latency worse, not better.

Increasing batch size is the first instinct for throughput improvement, and it does improve throughput — up to a point. Beyond the compute-saturation knee (roughly 20–30 requests, depending on GPU and model size), adding more requests to a batch causes latency to spike non-linearly. The throughput-latency curve has a hockey-stick shape: flat on the left, vertical on the right. Batching for throughput beyond that knee is directly trading P99 for aggregate efficiency.

Naive retry policies are designed for transient failures. A slow LLM response is not a failure — the model is still generating. If you apply standard exponential backoff to a request that hasn't responded in three seconds, you create a duplicate in-flight request on an already-saturated system, pushing the batch size further past the hockey-stick knee and worsening P99 for everyone else.

Standard LRU caching is optimal for uniform workloads but fails when conversation history creates heterogeneous context lengths. LRU can evict the KV cache for a long-running conversation right before that conversation needs it, forcing a full re-prefill and causing a latency spike precisely when the affected user is most engaged. Research on conversation-aware caching shows LRU eviction patterns worsen SLO violation rates compared to strategies that account for recency and expected reuse value.

Prioritizing TTFT over throughput — which appears correct for interactive workloads — causes decode stalls. A scheduler that eagerly prefills new requests interrupts ongoing decode batches, creating generation stall bubbles that spike P99 inter-token latency. Every improvement to TTFT achieved by preempting decode is a transfer of latency to the tail of the inter-token distribution for requests already in progress.

What Actually Reduces P99

The effective approaches all share a structure: they reduce the variance of service time rather than just the mean.

Chunked prefill divides long prompts into token-budget-sized chunks and interleaves them with decode steps. Since decode is memory-bandwidth-bound and leaves compute underutilized, prefill chunks can be co-scheduled without degrading decode throughput. This eliminates the spike caused by a long prefill preempting an ongoing decode batch. Production measurements show P99 inter-token latency dropping from 1.08 seconds to 0.29 seconds with chunked prefill on large models — roughly a 3.7x improvement with no change to model quality. Chunked prefill is now the default configuration in major serving frameworks.

Length-aware request routing separates short and long requests onto different GPU instances or batches. Mixing short and long sequences in a single batch creates GPU kernel inefficiencies from padding and inter-SM imbalance, adding 10–110% latency overhead relative to length-homogeneous batches. Routing that groups requests by predicted sequence length range reduces P99 tail latency by 25–69% depending on workload, with median latency improving by similar amounts and overall throughput roughly tripling.

Predicted-length routing can be implemented as a lightweight XGBoost classifier on input features, achieving around 5% mean absolute error on output length prediction — enough to route requests to the right length bucket without requiring expensive per-request profiling.

Speculative decoding uses a small, fast draft model to propose 5–8 tokens speculatively, with the large target model verifying all candidates in a single forward pass. When acceptance rates reach 60–80%, this achieves 2–3x reduction in inter-token latency. The gain is most pronounced at low GPU utilization; at saturation, the draft model competes for compute and the benefit decreases. Production deployments report 2.31x speedup on Llama 3.1-70B and 3.6x throughput on H100s with FP8 quantization.

Streaming as a perceived-latency fix does not reduce tail latency mathematically but transforms the user experience. Sending tokens as they are generated converts the problem from "wait 28 seconds for a response" to "wait 1–2 seconds for the first token, then read at generation speed." For interactive workloads, TTFT under three seconds and inter-token latency under 100ms (three to ten tokens per second, matching reading speed) is the target that matters. Tail latency on total completion time becomes invisible if the first tokens arrive quickly.

Admission control prevents the hockey-stick degradation from occurring in the first place. Keeping active batch size below the compute-saturation threshold — maintaining 20–30% spare capacity — preserves near-linear latency scaling. Proactive headroom-based scaling achieves higher effective throughput than reactive autoscaling precisely because it avoids the non-linear region entirely. Output length caps (for example, a 1,600-token hard limit on a heavy-tailed workload) can reduce queuing delay by 58% while fully serving 70% of requests without truncation.

Hedged requests address provider-level tail latency. If a backend hasn't responded within a latency threshold — say, two seconds for a 500ms P50 endpoint — fire the same request to a second provider and return whichever responds first. The duplicate request cost is roughly one in ten at a 2x threshold above P50; the P99 improvement is substantial when provider slowdowns are the latency source.

Measuring P99 for LLM Workloads

The most important change is decomposing latency into its two phases and tracking percentiles on each independently.

TTFT (time to first token) captures prefill cost and perceived responsiveness. Inter-token latency (ITL) or time per output token (TPOT) captures decode stability. An application can have excellent TTFT and catastrophic P99 ITL — or vice versa. Reporting a single E2E latency number hides both failure modes.

The metrics that matter in production:

  • TTFT at P50, P95, and P99 — alert if P95 TTFT exceeds one to two seconds for chatbot workloads
  • ITL at P99 — alert if it exceeds 500ms for interactive workloads (indicates decode stalls)
  • Goodput — the fraction of requests meeting both TTFT and ITL SLOs simultaneously; this is a better headline SLA metric than E2E latency at any single percentile
  • KV cache utilization — a leading indicator; spikes above 90% utilization predict incoming TTFT spikes as prefix cache misses increase
  • Request queue depth at P95 — a leading indicator for batch saturation before the hockey-stick knee is reached

Do not use average latency as a primary signal. The mean is dominated by the heavy tail and can swing dramatically without indicating anything about typical-user experience. Track P50 (typical user), P95 (unlucky user), and P99 (near worst-case) as separate series.

Histogram buckets need to span the full expected range: 50ms, 100ms, 200ms, 500ms, 1s, 2s, 5s, 10s, 30s. Standard API monitoring histograms that stop at 2–5 seconds will record every tail request as overflow, making the shape of the tail invisible.

The Diagnostic Sequence

When P99 is far worse than P50, work through this sequence:

  1. Separate TTFT from ITL. If TTFT P99 is high but ITL P99 is normal, the problem is context-length variance or KV cache eviction — prioritize length-aware routing and conversation-aware caching. If ITL P99 is high but TTFT is normal, the problem is decode stalls from prefill interference — prioritize chunked prefill.

  2. Check batch utilization. If GPU utilization is at or above the saturation knee, admission control is the fix. If it is below 50%, speculative decoding has room to improve ITL without competing for compute.

  3. Analyze the output length distribution. If your P99 output length is more than 3x your P50, you have a fundamental heavy-tail distribution problem. Length caps or length-aware routing will help more than any other single change.

  4. Audit retry logic. If your retry policy fires on slow responses rather than on failures, disable it or replace it with hedging. Retrying slow LLM requests is the single fastest way to convert a latency problem into a throughput collapse.

The 35x gap between P50 and P99 is not a monitoring artifact or an outlier to filter out. It is the shape of the distribution, and it will reappear in your next incident until the infrastructure is explicitly designed to manage variance rather than just mean throughput.

References:Let's stay in touch and Follow me for more thoughts and updates