DEV Community

fiercedash
fiercedash

Posted on

P99 Latency on 15 LLMs: An Engineer's Field Notes

P99 Latency on 15 LLMs: An Engineer's Field Notes

I've been running production AI workloads long enough to know that p50 numbers lie. Anyone can hit a great median latency once. What separates a toy demo from a 99.9% uptime production system is what happens at p99, when the autoscaler is cold-starting a new pod at 3 AM and your customer's CEO is typing into your chatbot. So I spent two weeks hammering fifteen different LLMs through Global API's edge to see which ones actually hold up under real conditions. Here's what I learned, what broke, and which models I'd stake my SLA on.

Why I Stopped Trusting the Marketing Pages

Every model card claims to be the fastest. Every provider has a benchmark that conveniently puts them at the top. The problem with those numbers is they're usually measured once, from a warm connection, on the provider's own fleet, with a prompt they cherry-picked. None of that matters when you're serving traffic from São Paulo to Seoul.

In my world, latency isn't a number on a dashboard. It's the budget between your customer's click and the first pixel of meaningful response. If your TTFT drifts above 400ms at p99, your chat product starts feeling like a 2014-era customer support widget. People tolerate a slow database query. They do not tolerate a slow AI.

So I set up a proper test harness through Global API at https://global-apis.com/v1, pointed it at two regions, and ran each model ten times. Not three. Not five. Ten runs, average reported, with streaming enabled the whole way. I wanted sustained throughput, not a single lucky request.

My Test Rig

Here's the setup I used. Nothing exotic, just the kind of thing any platform team could replicate:

Parameter Value
Test Date May 20, 2026
Test Region (Primary) US East (Ohio)
Test Region (Secondary) Asia (Singapore)
Test Prompt "Explain recursion in 200 words"
Output Tokens ~150 per request
Iterations 10 runs, average recorded
Streaming Yes (SSE)
Endpoint https://global-apis.com/v1

The prompt is intentionally boring. I don't care about creativity here. I care about tokens-per-second, TTFT, and how those numbers move when the network is the bottleneck instead of the model. A 200-word recursion explanation lands right around 150 tokens of output, which is enough to measure sustained throughput without padding the response with noise.

The Headline Results

After crunching all ten iterations per model, here's how the field shakes out. Sorted by raw speed, not by quality or cost:

Rank Model TTFT (ms) Tokens/sec Provider $/M Output
1 Step-3.5-Flash 120 80 StepFun $0.15
2 Qwen3-8B 150 70 Qwen $0.01
3 DeepSeek V4 Flash 180 60 DeepSeek $0.25
4 Hunyuan-TurboS 200 55 Tencent $0.28
5 Doubao-Seed-Lite 220 50 ByteDance $0.40
6 Qwen3-32B 250 45 Qwen $0.28
7 Hunyuan-Turbo 280 42 Tencent $0.57
8 GLM-4-32B 300 38 Zhipu $0.56
9 Qwen3.5-27B 350 35 Qwen $0.19
10 DeepSeek V4 Pro 400 30 DeepSeek $0.78
11 MiniMax M2.5 450 28 MiniMax $1.15
12 GLM-5 500 25 Zhipu $1.92
13 Kimi K2.5 600 20 Moonshot $3.00
14 DeepSeek-R1 800 15 DeepSeek $2.50
15 Qwen3.5-397B 1200 10 Qwen $2.34

One quick note: the reasoning-style models (R1, K2.5, and friends) have a TTFT that includes internal "thinking" time. The first visible token to your user is delayed because the model is quietly reasoning first. If you're building a customer-facing product, that hidden thinking time is the latency you actually feel.

Where I Land on Auto-Scaling Strategy

Most teams I talk to pick one model and call it done. That's a recipe for a brittle system. My rule of thumb after running these tests: keep at least three models in rotation, each for a different tier of traffic.

Tier 1: The Firehose (ultra-cheap, fast enough to be invisible)

Model tok/s $/M Output
Qwen3-8B 70 $0.01
Step-3.5-Flash 80 $0.15

Qwen3-8B at $0.01 per million output tokens is, frankly, absurd. Seventy tokens per second means your users see a steady stream of words scrolling in, and at a tenth of a cent per million tokens you can auto-scale horizontally without ever opening a finance ticket. I use this tier for spam classification, intent detection, simple autocomplete, and the first line of any agentic pipeline.

Tier 2: The Workhorse (balanced quality and speed)

Model tok/s $/M Output
DeepSeek V4 Flash 60 $0.25
Hunyuan-TurboS 55 $0.28
Qwen3-32B 45 $0.28

This is the band where most production chat traffic should live. DeepSeek V4 Flash is my default pick — 60 tok/s sustained, 180ms TTFT, and the output quality is in GPT-4o territory for anything short of a PhD-level reasoning question. At $0.25 per million tokens you can serve tens of millions of completions a day without breaking your margin.

Tier 3: The Specialist (slower, smarter, route by intent)

Model tok/s $/M Output
Doubao-Seed-Lite 50 $0.40
GLM-4-32B 38 $0.56
Hunyuan-Turbo 42 $0.57
DeepSeek V4 Pro 30 $0.78

Once you cross into the mid-range, throughput drops because you're paying for larger context windows and better instruction following. DeepSeek V4 Pro at 30 tok/s is roughly half the speed of V4 Flash, but if your task involves long-document analysis or multi-step planning, the quality delta is worth it.

Tier 4: The Heavy Hitter (quality above all, accept the latency)

Model tok/s $/M Output
MiniMax M2.5 28 $1.15
GLM-5 25 $1.92
Kimi K2.5 20 $3.00
DeepSeek-R1 15 $2.50
Qwen3.5-397B 10 $2.34

These models live at the bottom of the speed chart because they're not trying to be fast. They exist for the queries where correctness matters more than user-perceived snappiness — code review, legal summarization, anything where a hallucination costs real money. I keep them as a fallback in my routing layer, not as the default.

Multi-Region Matters More Than You'd Think

The single biggest surprise from this round of testing was how much the geography shifted things. I ran the same benchmark suite from US East and from Singapore. Here's what came back:

Model US East TTFT Asia TTFT Delta
DeepSeek V4 Flash 180ms 150ms -30ms
Qwen3-32B 250ms 210ms -40ms
GLM-5 500ms 420ms -80ms
Kimi K2.5 600ms 480ms -120ms

The Asian-originated models (Qwen, GLM, Kimi) get a 16-20% latency reduction when called from Asia because their inference fleets are physically closer. That's not a small optimization — at scale, 80ms of TTFT can flip a model from "feels fast" to "feels slow" on the user-perception curve.

The interesting case is DeepSeek. Their infrastructure is genuinely well-distributed globally. The delta from US to Asia for V4 Flash was only 30ms, which tells me they've done the CDN work that most providers skip. If you're serving a multi-region product and you can only pick one model for the default tier, DeepSeek V4 Flash is the safest bet because it doesn't punish you for being far from the inference cluster.

P99 Is Where Dreams Go to Die

Here's the part of the post where I get a little salty. The numbers above are averages. Averages hide the tail. The difference between a model with 180ms average TTFT and 380ms p99 TTFT is the difference between "this is fast" and "this is occasionally awful." I won't publish my exact p99 numbers in a public post (security through obscurity, my friends), but I will tell you that the models I trust are the ones whose p99 stays under 1.5x their median. Anything worse, and you'll start seeing timeout cascades under load.

If you're targeting a 99.9% SLA — and you should be, because that's table stakes for any B2B product — your budget per request is roughly 8.7 hours of downtime per year. Sound like a lot? It isn't. A single cold-start spike that takes out 0.5% of your traffic for an hour will burn through your entire annual SLA budget. Pick models whose p99 you trust, not models whose median looks good on a slide.

The Routing Layer I Actually Use

Let me share the routing code I have running in production. It's nothing fancy — just a tier-based router that picks a model based on the request type, with a timeout budget that fails over to a faster (but dumber) model if the primary one drags. This is the kind of code that survives a 3 AM page.


python
import os
import time
import requests
from typing import Optional

BASE_URL = "https://global-apis.com/v1"
API_KEY = os.environ["GLOBAL_API_KEY"]

TIER_CONFIG = {
    "firehose": ("Qwen3-8B", 250, 0.01),
    "workhorse": ("DeepSeek V4 Flash", 350, 0.25),
    "specialist": ("DeepSeek V4 Pro", 700, 0.78),
    "heavy": ("GLM-5", 900, 1.92),
}

def classify_request(prompt: str) -> str:
    """Route based on simple heuristics. Real version uses a classifier."""
    if len(prompt) < 200 and "summarize" not in prompt.lower():
        return "firehose"
    if "code" in prompt.lower() or "analyze" in prompt.lower():
        return "specialist"
    if len(prompt) > 4000:
        return "heavy"
    return "workhorse"

def call_with_failover(prompt: str, tier: str, timeout_ms: int =
Enter fullscreen mode Exit fullscreen mode

Top comments (0)