Deel:𝕏LinkedInRedditFacebookKopieer link

Latency meten met percentielen in plaats van gemiddeldes

Door Ivo Donker — samengesteld met AI-ondersteuning (Claude & Gemini) · Laatst bijgewerkt: 7 augustus 2026

Bij het evalueren van de prestaties van Large Language Model (LLM) API's is responstijd (latency) een van de meest kritieke bedrijfsparameters. Toch trappen veel engineeringteams en technische beslissers in de valkuil om latency uit te drukken in een enkel gemiddelde. In een traditionele webapplicatie kan een gemiddelde responstijd al een vertekend beeld geven, maar bij LLM-infrastructuur is het rekenkundig gemiddelde ronduit misleidend.

LLM-interacties vertonen geen klassieke normaalverdeling (de bekende klokcurve), maar een sterk scheve verdeling met een extreem lange staart (een zogenaamde heavy-tailed distribution). Wie beslissingen neemt op basis van gemiddeldes, negeert de frustrerende ervaring van de 5 tot 10 procent gebruikers die te maken krijgen met onaanvaardbaar trage verzoeken. In deze handleiding behandelen we waarom de latencyverdeling bij LLM's zo scheef is, hoe je percentielen (p50, p90, p95, p99) leest, hoe je metingen correct corrigeert voor uitvoerlengte en welke valkuilen er bestaan bij het aggregere en opstellen van een Service Level Objective (SLO).

Waarom het gemiddelde faalt bij LLM-latency

Het rekenkundig gemiddelde wordt berekend door de som van alle gemeten responstijden te delen door het totale aantal metingen. Deze metriek is uitermate gevoelig voor uitschieters (outliers). Wanneer negentien verzoeken binnen 500 milliseconden worden afgehandeld, maar het twintigste verzoek duurt 30 seconden vanwege een koudestart-mechanisme of een herpoging, stijgt het gemiddelde voor alle twintig verzoeken direct naar bijna 2 seconden.

Dat gemiddelde van 2 seconden vertelt je echter twee dingen niet:

Voor een breder overzicht van het opzetten van prestatiemetingen kun je onze gids over snelheid meten bij LLM's raadplegen, maar de kernoorzaak van dit specifieke latencygedrag ligt in de architectuur van AI-cloudproviders.

De oorzaken van de lange staart bij LLM-API's

De responstijd van een LLM-endpoint wordt niet alleen bepaald door de hoeveelheid rekenkracht die nodig is voor een prompt, maar door een keten van dynamische factoren bij de provider:

Wat p50, p95 en p99 precies betekenen

Om de verdeling van responstijden goed te begrijpen, maken we gebruik van percentielen. Een percentiel is een drempelwaarde die aangeeft welk percentage van de metingen op of onder die waarde valt wanneer je alle metingen van klein naar groot sorteert.

Percentiel Betekenis in de praktijk Operationele focus
p50 (Mediaan) 50% van de verzoeken was sneller dan deze waarde, 50% was trager. Dit is de 'typische' ervaring. Inzicht in de algemene efficiëntie van de infrastructuur onder normale omstandigheden.
p90 90% van de verzoeken was sneller dan deze waarde; 10% ondervond meer vertraging. Eerste indicatie van opbouwende drukte of lichte capaciteitsgebreken.
p95 95% van de verzoeken viel binnen deze tijd. 1 op de 20 verzoeken was trager. De standaard grens voor het opstellen van gebruikersgericht kwaliteitsbeleid (SLA/SLO).
p99 99% van de verzoeken was sneller. Slechts 1% (1 op de 100) was trager. Detecteren van zeldzame maar ernstige systeemfouten, koude starts en extreme wachtrijen.

Stel dat we een fictieve reeks van 100 verzoeken meten. Als de p50 op 800 ms ligt, de p95 op 1.200 ms en de p99 op 14.500 ms, dan betekent dit dat de meeste gebruikers een zeer snelle ervaring hebben, maar dat 1 op de 100 gebruikers bijna 15 seconden moet wachten. Het gemiddelde van deze reeks zou rond de 1.100 ms liggen, waardoor de p99-piek van 14,5 seconden volledig onzichtbaar blijft in de stuurgetallen.

Het onderscheid tussen TTFT en totale antwoordtijd

Bij het meten van LLM-latency is het maken van onderscheid tussen twee fasen in het generatieproces essentieel: de verwerking van de invoer (prefill) en het genereren van de uitvoer (decode). Deze twee fasen hebben een heel ander prestatieprofiel.

1. Time To First Token (TTFT)

TTFT is de tijd die verstrijkt tussen het verzenden van de HTTP-request door de client en het ontvangen van het allereerste token van de LLM-respons. TTFT omvat de netwerktijd, de tijd in de wachtrij van de provider en de prefill-fase waarin het model de gehele invoerprompt in één keer verwerkt.

Een hoge TTFT wijst vrijwel altijd op lange invoerprompts, drukte in de wachtrijen van de provider of netwerkvertraging. Voor de interactieve gebruikerservaring (bijvoorbeeld een chat-interface) is TTFT de belangrijkste metriek: het bepaalt hoe snel de gebruiker ziet dat het systeem 'begint te typen'.

2. Totale antwoordtijd en Time Per Output Token (TPOT)

De totale antwoordtijd is de tijd vanaf het verzoek tot de ontvangst van het allerlaatste token (of het sluiten van de stream). De totale tijd is echter sterk afhankelijk van hoeveel tokens het model heeft gegenereerd. Een antwoord van 500 tokens duurt logischerwijs langer dan een antwoord van 20 tokens.

Daarom splitsen we de meting op in twee heldere componenten:

Let op: Analyseer TTFT en TPOT altijd als gescheiden percentielverdelingen. Een model kan een uitstekende p50 TTFT hebben (200 ms), maar een slechte p95 TPOT (80 ms per token), waardoor lange antwoorden halverwege toch traag aanvoelen.

Waarom je uitvoerlengte moet normaliseren

Als je twee LLM-providers of twee modelversies met elkaar wilt vergelijken, kun je de absolute totale responstijden niet zomaar naast elkaar leggen. Als Model A in 2 seconden een antwoord geeft van 50 tokens, en Model B doet er 4 seconden over maar genereert 300 tokens, dan is Model B in de generatiefase significant sneller (75 tokens/sec vs 25 tokens/sec), hoewel de absolute responstijd van Model B twee keer zo hoog is.

Zonder normalisatie verval je in een vergelijking die afhankelijk is van de toevallige lengte van het gegenereerde antwoord op dat specifieke moment. Raadpleeg ons uitgebreide stappenplan voor een eigen benchmark voor meer richtlijnen over het opzetten van gestandaardiseerde testsets.

Om latency correct te vergelijken op percentielniveau, pas je de volgende normalisatiestappen toe:

  1. Groepeer benchmarks op basis van een vastgestelde promptlengte (bijv. prompts van ~500 tokens).
  2. Evalueer de p50, p95 en p99 van de TTFT om de prompt-verwerkingscapaciteit te vergelijken.
  3. Evalueer de p50, p95 en p99 van de TPOT (of TPS) om de generatiesnelheid te vergelijken.

Het aggregatieprobleem: percentielen mag je niet middelen

Een van de meest gemaakte wiskundige fouten in monitoring-dashboards is het middelen van percentielen. Stel dat je applicatie op vijf verschillende servers draait. Elke server berekent elk uur zijn eigen p95 latency. Veel ontwikkelaars neigen ernaar om het gemiddelde te nemen van die vijf p95-waarden om de 'totale p95' van het uur te bepalen. Dit is statistisch invalide.

Percentielen zijn niet-lineair en niet-additief. De p95 van een gecombineerde dataset kan veel hoger of lager liggen dan het gemiddelde van de individuele p95-waarden, afhankelijk van het volume en de verdeling van de metingen per server.

Fictief rekenvoorbeeld van de aggregatiefout

Stel dat Server A 1.000 verzoeken afhandelt met een p95 van 1.000 ms. Server B handelt slechts 10 verzoeken af, maar door een incident was de p95 daar 20.000 ms. Neem je het eenvoudige gemiddelde van de twee p95's, dan kom je uit op (1.000 + 20.000) / 2 = 10.500 ms. In werkelijkheid vielen 950 van de 1.010 totale verzoeken ruim onder de 1.000 ms, waardoor de werkelijke gecombineerde p95 dicht bij de 1.000 ms ligt. Het gemiddelde van de percentielen geeft hier een volstrekt verkeerd beeld.

Wat moet je wél doen?

Keteneffecten: hoe de staart zich opbouwt in RAG en agents

In moderne AI-architecturen staat een LLM-call zelden op zichzelf. Denk aan een Retrieval-Augmented Generation (RAG) pipeline waarbij eerst een embedding-model wordt aangeroepen, vervolgens een vector-database wordt geraadpleegd, daarna een reranker draait en ten slotte het hoofdmodel een antwoord genereert. In een multi-agent systeem worden soms wel tientallen LLM-calls in serie of parallel uitgevoerd.

Wanneer meerdere stappen sequentieel worden uitgevoerd, stapelen de percentielen zich op een gevaarlijke manier op. De totale p99 van een keten is drastisch slechter dan de p99 van de individuele onderdelen.

Als een keten bestaat uit $n$ onafhankelijke stappen, en elke stap heeft een p99-latency van 1 seconden (wat betekent dat 1% van de calls erg traag is), dan is de kans dat een verzoek geen enkele p99-vertraging oploopt gelijk aan $0{,}99^n$.

Aantal sequentiële stappen ($n$) Kans dat álles snel verloopt ($0{,}99^n$) Kans dat ten minste 1 stap de p99-staart raakt
1 stap 99,0% 1,0%
5 stappen 95,1% 4,9%
10 stappen 90,4% 9,6%
50 stappen (complex agentic proces) 60,5% 39,5%

Bij een proces met 50 stappen krijgt bijna 40% van de eindgebruikers te maken met de p99-latency van ten minste één subsysteem! Dit fenomeen noemt men tail latency amplification. Om deze reden moeten de p95- en p99-eisen voor individuele bouwstenen in een RAG-keten vele malen strenger zijn dan de uiteindelijke SLO die aan de gebruiker wordt beloofd.

Steekproefgrootte: hoeveel metingen heb je nodig?

Een veelgemaakte fout bij benchmarks is het rapporteren van een p99 op basis van een te kleine steekproef. Als je een benchmark uitvoert met 50 verzoeken en daaruit 'de p99' berekent, is de uitkomst puur statistische ruis.

Het 99e percentiel vertegenwoordigt immers een gebeurtenis die slechts in 1 op de 100 gevallen voorkomt. Om het 99e percentiel met een acceptabele betrouwbaarheid te kunnen bepalen, heb je een absolute ondergrens aan waarnemingen nodig.

Draai je een snelle test van 30 prompts om een nieuw model uit te proberen? Kijk dan uitsluitend naar p50 en eventueel p90. Trek geen conclusies over de p99 van een provider op basis van enkele tientallen test-requests.

Client-side versus Server-side metingen

Waar meet je de latency? In de praktijk zit er een aanzienlijk verschil tussen wat de API-provider in zijn statusdashboard rapporteert (server-side latency) en wat de eindgebruiker van jouw applicatie daadwerkelijk ervaart (client-side latency).

Server-side latency (Provider perspectief)

De provider meet de tijd vanaf het moment dat het verzoek hun loadbalancers binnenkomt tot het moment dat het laatste token hun netwerkpoort verlaat. Wat hierin ontbreekt:

Client-side latency (Jouw perspectief)

Client-side latency omvat de volledige round-trip time (RTT), inclusief eventuele vertragingen in het verwerken van de HTTP-respons door jouw eigen SDK of applicatiecode. Verder kan een lokale garbage collection pauze in Node.js of Python de gemeten latency artificieel verhogen.

Advies voor benchmarking: Gebruik voor besluitvorming altijd client-side metingen vanaf de exacte locatie en netwerkomgeving waar jouw applicatie later in productie draait. Voor uitgebreide instructies over het inrichten van je observabiliteit kun je de gids over observability en logging bij LLM-API's raadplegen.

De invloed van retries, timeouts en streaming

De manier waarop je applicatie omgaat met fouten en netwerkstreams heeft een directe impact op de gemeten percentielen.

1. Retries en Backoff

Wanneer een LLM-verzoek faalt met een HTTP 503 (Capacity Exceeded) of een HTTP 429 (Rate Limit), zal een robuuste client het verzoek opnieuw proberen met een korte vertraging (exponential backoff). Meer details over hoe je dit configureert vind je op de pagina over retries en backoff-strategieën.

Als je pas de latency registreert zodra het verzoek uiteindelijk slaagt, telt de wachttijd van de mislukte pogingen mee in de totale duur. Een verzoek dat twee keer faalt en pas bij de derde poging slaagt, schiet direct door naar de p99-staart. Registreer daarom zowel de latency van de poging (per HTTP-call) als de latency van de transactie (de totale tijd die de eindgebruiker wacht inclusief herpogingen).

2. Time-outs en clementie-bias

Als je een harde client-side time-out instelt op bijvoorbeeld 10 seconden, worden alle verzoeken die langer dan 10 seconden duren afgebroken en als fout gemarkeerd. Zie voor de verwerking hiervan onze handleiding over timeouts en cancellation.

Als je deze afgebroken verzoeken vervolgens verwijdert uit je latency-statistieken, ontstaat er truncation bias: je p99 lijkt opeens kunstmatig laag (onder de 10 seconden), simpelweg omdat je de echt trage responses hebt afgesneden. Neem afgebroken verzoeken met de maximale geconfigureerde time-outwaarde op in je percentielberekeningen, of rapporteer het foutpercentage expliciet naast je percentielen.

3. Streaming-buffering

Bij het gebruik van streaming HTTP-responses sturen veel client-SDK's of proxy's tokens pas door naar de applicatie wanneer een buffer van een bepaalde grootte (bijv. 4 KB) vol is. Dit beïnvloedt de TTFT-meting negatief. Zorg er bij latencymetingen voor dat netwerkbuffers op de client uitstaan (unbuffered stream) om de daadwerkelijke fysieke TTFT te meten.

Vertaling naar SLO's, SLA's en Foutbudgetten

Het overstappen van gemiddeldes naar percentielen stelt je in staat om reële Service Level Objectives (SLO's) af te spreken met het team of met de business. Een afspraak als *"Onze LLM-dienst heeft een gemiddelde responstijd van 1,5 seconde"* is waardeloos, omdat het geen garanties biedt voor individuele verzoeken.

Een professionele SLO-definitie op basis van percentielen ziet er als volgt uit:

Voorbeeld van een robuuste LLM SLO:
"In 95% van de gevallen over een rollend venster van 30 dagen moet de Time To First Token (TTFT) kleiner zijn dan 800 ms, en moet de Time Per Output Token (TPOT) lager liggen dan 40 ms/token. Verzoeken die langer duren dan 15 seconden worden als mislukt beschouwd."

Het koppelen van een Foutbudget (Error Budget)

Een grens stellen op de p95 betekent automatisch dat je accepteert dat 5% van de verzoeken de norm mag overschrijden. Dit is je foutbudget. Pas wanneer meer dan 5% van de verzoeken trager is dan de p95-norm (of wanneer de p99 een kritieke bovengrens van bijvoorbeeld 20 seconden overschrijdt), raakt het foutbudget uitgeput.

Op dat moment heeft het team een helder signaal om te grijpen naar maatregelen zoals:

Veelgemaakte fouten bij LLM-latencymetingen

Ter afsluiting een overzicht van de meest voorkomende valkuilen in de praktijk, en wat de juiste aanpak is:

Foutieve aanpak Waarom het misgaat De correcte methode
Sturen op gemiddelde latency. Verbergt de trage ervaring van de staartgebruikers en reageert extreem op uitschieters. Stuur op p50 voor de mediaanervaring en p95/p99 voor de staart.
Gemiddelde nemen van p95-waarden over meerdere servers. Statistisch invalide; vervalst het echte percentiel. Sla ruwe data op of gebruik t-digest / HDR Histograms voor aggregatie.
Totale tijd vergelijken zonder te corrigeren voor tokenlengte. Modellen die uitgebreidere antwoorden geven lijken onterecht 'trager'. Splits in TTFT (ms) en TPOT (ms/token of TPS).
p99 rapporteren op basis van 30 testverzoeken. Te kleine steekproef leidt tot willekeurige ruis. Evalueer p99 pas bij minimaal 1.000 representatieve verzoeken.
Time-outs schrappen uit de latencydataset. Leidt tot truncation bias, waardoor de p99 kunstmatig laag lijkt. Reken geannuleerde/ge-timeoutte verzoeken mee tegen de maximale duur.

Door percentielen consequent en op de juiste manier toe te passen in je evaluaties, benchmarks en productiemonitoring, transformeer je latency van een vage indruk naar een harde, stuurbare kwaliteitsmetriek voor je AI-infrastructuur.