Stel je dit voor: je team heeft weken aan een nieuwe functionaliteit gewerkt. De load test draait, en de response time ziet er prima uit, gemiddeld 180 milliseconden. Iedereen is tevreden want dat is ruim binnen de norm, en alles gaat live.
Drie uur later crasht de applicatie, en de vraag is: wat ging er mis? De response time was inderdaad goed, maar de CPU draaide tijdens de test al op 94%. En het geheugengebruik groeide langzaam maar gestaag, zonder dat iemand ernaar keek. Want “de response time was toch goed?”
Dit gebeurt vaker dan je denkt, want teams die alleen naar response time kijken missen het grotere plaatje. Goede performance testing draait namelijk niet om een enkele metric, maar om vijf metrics die samen het complete verhaal vertellen.
In dit artikel leer je welke dat zijn, welke doelwaarden je moet hanteren, en hoe je ze samen interpreteert, zodat je nooit meer verrast wordt door een crash die je had kunnen zien aankomen.
Waarom performance testing metrics je complete beeld geven
Performance bugs zijn anders dan functionele bugs: ze duiken niet op tijdens een handmatige test met een enkele gebruiker, maar manifesteren zich pas wanneer je systeem onder druk staat. Hoe performance testen zich verhoudt tot andere testvormen lees je in ons uitgebreidere overzicht. Daarom zijn performance testing metrics (meetwaarden die laten zien hoe je systeem presteert onder belasting) zo belangrijk, omdat ze zichtbaar maken wat je anders pas in productie merkt. Performance testing is daarmee een essentieel onderdeel van niet-functioneel testen, dat zich richt op hoe je systeem werkt in plaats van wat het doet.
Zonder die metrics vlieg je blind: je weet niet of je systeem honderd of tienduizend gebruikers aankan, je ziet niet dat je geheugen langzaam lekt, en je mist de waarschuwingssignalen voordat het te laat is. Met de juiste metrics maak je daarentegen datagedreven beslissingen, omdat je precies ziet waar de bottleneck (het knelpunt dat je systeem vertraagt) zit en wanneer het tijd is om op te schalen.
De vijf essentiële metrics vormen samen dat complete beeld:
| Metric | Wat het meet | Waarom het ertoe doet |
|---|---|---|
| Response time | Hoe snel je systeem reageert | Directe gebruikerservaring |
| Throughput | Verzoeken per seconde | Capaciteitsindicator |
| Error rate | Percentage mislukte verzoeken | Betrouwbaarheid onder belasting |
| CPU-gebruik | Processorbelasting | Schaalbaarheid en ademruimte |
| Geheugengebruik | RAM-verbruik over tijd | Stabiliteit op lange termijn |
Mis je er een, dan mis je bij je performance testing belangrijke informatie. Laten we ze een voor een doorlopen.
Response time: waarom 200 milliseconden het verschil maakt
Response time is de tijd tussen het moment dat een gebruiker een actie uitvoert en het moment dat je applicatie reageert. Het bepaalt direct hoe snel je applicatie aanvoelt, en dat gevoel is belangrijker dan je misschien denkt.
Onderzoek van Google laat zien dat 53% van mobiele gebruikers afhaakt als een pagina langer dan 3 seconden laadt, maar de perceptie van snelheid begint veel eerder:
Onder 100 milliseconden voelt een reactie instant, alsof er geen vertraging is. Tussen 100 en 300 milliseconden voelt het nog steeds responsief, hoewel een lichte vertraging merkbaar is. Zodra je boven de 300 milliseconden komt, wordt de vertraging duidelijk voelbaar en begint alles traag aan te voelen. Boven de 1 seconde dwaalt de aandacht af en stijgt de bounce rate (het percentage bezoekers dat de pagina verlaat).
Daarom is 200 milliseconden de gouden standaard voor kritieke paden zoals een checkout of betaalflow, terwijl voor standaard API-aanroepen 500 milliseconden een goed target is en achtergrondprocessen tot zo’n 2 seconden mogen duren.
Meet daarbij altijd je p95 en p99 in plaats van het gemiddelde, want het 95e percentiel (p95) betekent dat 95% van alle verzoeken sneller is dan die waarde. Een gemiddelde van 200 milliseconden ziet er prima uit, maar als je p95 op 800 milliseconden zit ervaart een op de twintig gebruikers een trage applicatie. Bij duizenden bezoekers per dag zijn dat honderden gefrustreerde mensen, en het gemiddelde verbergt die uitschieters terwijl de p95 ze blootlegt.
Snelle response times alleen zijn echter niet genoeg. Want wat als je systeem snel is, maar slechts tien verzoeken per seconde aankan?
Throughput: hoeveel aankan je systeem echt?
Throughput (doorvoer) meet hoeveel verzoeken je systeem per seconde kan verwerken. Waar response time vertelt hoe snel een individueel verzoek wordt afgehandeld, vertelt throughput hoeveel verzoeken je systeem tegelijkertijd aankan. Het is dus je capaciteitsindicator.
Om je target throughput te bepalen, begin je bij je huidige productieverkeer. De JMeter-documentatie legt goed uit hoe je dit in de praktijk meet en configureert. Monitor je applicatie gedurende een normale werkdag en noteer de pieken. Stel dat je webshop gemiddeld 100 verzoeken per seconde verwerkt, met pieken tot 250 tijdens de lunchpauze. Dan is een verstandig target 300 verzoeken per seconde: je piek plus 20% groeimarge. Voor een Black Friday-scenario wil je het dubbele aankunnen, dus 600 verzoeken per seconde.
Neem als voorbeeld een middelgrote e-commerce site met het volgende dagpatroon:
| Tijdstip | Verzoeken/seconde | Load test target |
|---|---|---|
| Ochtend | 80 | 130 (doorlopend, +20%) |
| Lunchpiek | 250 | 300 (piekbelasting) |
| Middag | 120 | – |
| Avond | 180 | 600 (stresstest, 2x piek) |
De relatie tussen throughput en response time is bovendien heel belangrijk. Bij lage belasting is je response time doorgaans prima. Maar zodra je de throughput-limiet nadert, begint je response time steil te stijgen, en als je erover heen gaat, schiet ook de error rate omhoog. En daarmee komen we bij de volgende metric.
Error rate: wanneer wordt degradatie een probleem?
Error rate is het percentage mislukte verzoeken onder belasting. Het meet hoe betrouwbaar je systeem blijft wanneer het onder druk staat, en juist dat is waar het in productie op aankomt.
De acceptabele error rate hangt af van het type belasting:
Bij normale belasting is het target 0%, want elke fout duidt dan op een bug die je moet oplossen. Bij piekbelasting zoals een Black Friday is minder dan 1% acceptabel: lichte degradatie mag, maar structureel falen niet. Tijdens een stresstest waarbij je opzettelijk de grenzen opzoekt, is minder dan 5% nog acceptabel. Kom je boven de 10%? Dan is je systeem gewoon nog niet klaar voor productie.
Een concreet voorbeeld maakt dit tastbaar bij een webapplicatie met oplopende belasting:
| Gebruikers | Error rate | Response time | Beoordeling |
|---|---|---|---|
| 100 | 0% | 150 ms | Ruim binnen capaciteit |
| 500 | 0,3% | 320 ms | Prima, lichte stijging |
| 1.000 | 2% | 850 ms | Piekcapaciteit, merkbare degradatie |
| 2.000 | 15% | 2.500 ms | Breekpunt, opschalen noodzakelijk |
Bij 1.000 gebruikers zie je al merkbare degradatie, en bij 2.000 is het breekpunt bereikt. Je weet nu dat je moet opschalen of je code moet verbeteren voordat je die grens bereikt.
Minstens zo belangrijk als het percentage is het type fout dat optreedt, omdat elk type om een andere aanpak vraagt:
- Timeouts – wijzen op een te traag systeem
- 500-fouten – duiden op servercrashes
- Connection refused – maximale verbindingen bereikt
- Geheugenfouten – wijzen op een memory leak (een geheugenlek waarbij je applicatie steeds meer geheugen claimt zonder het vrij te geven)
Een foutanalyse is echter pas echt waardevol als je ook weet hoeveel ruimte je infrastructuur nog heeft.
CPU-gebruik: waarom 80% al een waarschuwing is
CPU-gebruik meet het percentage processorkracht dat je applicatie verbruikt. Het is je belangrijkste indicator voor schaalbaarheid, want het vertelt hoeveel ruimte je systeem nog heeft om pieken op te vangen.
Het target voor productie is minder dan 70% doorlopend gebruik, en dat klinkt misschien conservatief maar de reden is simpel. Stel dat je systeem normaal op 60% CPU draait: een verkeerspiek van 50% duwt je CPU dan naar 90%, wat oncomfortabel maar hanteerbaar is. Draai je echter al op 85% bij normale belasting, dan duwt diezelfde piek je naar 100%, waarna het systeem verzoeken gaat vertragen en er timeouts oplopen.
| CPU-niveau | Status | Actie |
|---|---|---|
| Onder 70% | Gezond | Voldoende ademruimte voor pieken |
| 70-80% | Waarschuwing | Monitoring verhogen, schaalplan voorbereiden |
| 80-95% | Kritiek | Opschalen noodzakelijk |
| Boven 95% | Acuut risico | Direct ingrijpen vereist |
Let tijdens je load test ook op het patroon van je CPU-gebruik: bij een gezond systeem stijgt de CPU lineair met de belasting, stabiliseert op een acceptabel niveau en daalt snel na een piek. Een ongezond patroon is wanneer de CPU razendsnel naar 100% schiet en traag weer daalt na de belasting, wat kan wijzen op een geheugenlek of inefficiente verwerkingslogica.
CPU vertelt je dus hoeveel ademruimte je systeem heeft. Maar er is nog een resource die stilletjes kan opraken zonder dat je het merkt, en die is minstens zo verraderlijk.
Memory usage: de stille tijdbom in je applicatie
Geheugengebruik meet hoeveel werkgeheugen (RAM) je applicatie verbruikt. Waar CPU-problemen zich meestal snel manifesteren, zijn geheugenproblemen verraderlijk: ze bouwen langzaam op en slaan pas toe nadat je systeem uren of zelfs dagen heeft gedraaid.
Dat maakt memory leaks (geheugenlekken, waarbij je applicatie geleidelijk meer geheugen claimt zonder het vrij te geven) zo gevaarlijk. Tijdens een korte load test van een uur stijgt het geheugengebruik misschien van 2 naar 2,1 gigabyte. Dat ziet er onschuldig uit. Maar als je diezelfde test 24 uur laat draaien, kan het oplopen tot 8 gigabyte, waarna je systeem crasht.
Daarom is het target niet een specifiek getal, maar stabiliteit: na een opwarmperiode hoort het geheugengebruik een plateau te bereiken en daar te blijven. Een gezond patroon laat zien dat het geheugen na een tot twee uur stabiliseert en daarna constant blijft, ook na 8 of zelfs 24 uur. Een ongezond patroon toont continue groei, uur na uur, zonder af te vlakken.
Om memory leaks betrouwbaar te detecteren moet je dus langer testen dan de meeste teams gewend zijn: minimaal 4 uur doorlopende belasting, en liever 24 uur voor kritieke applicaties. Veelvoorkomende oorzaken zijn onder andere:
- Event listeners die niet worden opgeruimd
- Caches zonder maximale grootte
- Databaseverbindingen die niet worden gesloten
- Circulaire referenties tussen objecten
Memory profiling tools (hulpmiddelen die precies laten zien waar geheugen wordt verbruikt) als JVisualVM voor Java, dotMemory voor .NET of clinic voor Node.js helpen je bij het opsporen van de exacte oorzaak.
Nu je de vijf metrics kent, is de volgende vraag hoe je ze in de praktijk meet.
De juiste tools kiezen (en het hoeft niet duur te zijn)
Goede performance testing vereist goede tooling, maar dat betekent niet dat je diep in de buidel hoeft te tasten. Een uitgebreid overzicht van beschikbare opties vind je in ons artikel over performance testing tools in 2026.
| Tool | Sterktes | Geschikt voor |
|---|---|---|
| JMeter | Gratis, enorme community, plugins voor elk protocol | Teams met beperkt budget |
| k6 | Modern, JavaScript-based, naadloze CI/CD-integratie | Developer-teams die automatiseren |
| Gatling | Miljoenen verzoeken, mooie HTML-rapporten | JVM-teams met schaalbehoeftes |
| LoadRunner | Meest complete oplossing voor complexe applicaties | Enterprises met ruim budget |
De aanbeveling voor de meeste teams is om te beginnen met k6 als je een modern en toegankelijk platform wilt, of met JMeter als budget de doorslag geeft. Beide tools meten alle vijf de metrics die je nodig hebt.
Nu je weet wat je bij performance testing meet en waarmee, is de laatste en misschien wel belangrijkste vraag: hoe interpreteer je de resultaten?
Hoe lees je je resultaten als samenhangend verhaal?
De kracht van deze vijf metrics zit niet in de individuele getallen, maar in hoe ze samen een verhaal vertellen. Kijk daarom nooit naar een metric los van de rest.
Response time en throughput vertellen samen hoe gebruikers je applicatie ervaren: lage response time gecombineerd met hoge throughput betekent een soepele gebruikerservaring, maar zodra een van de twee achterblijft merken je gebruikers dat direct. Error rate vertelt of je systeem betrouwbaar blijft wanneer het er echt op aankomt, terwijl CPU-gebruik en geheugengebruik toekomstige problemen voorspellen: hoge CPU betekent dat je binnenkort moet opschalen, en groeiend geheugen betekent dat je nu een lek moet fixen.
Neem als voorbeeld een load test met 500 gelijktijdige gebruikers. Stel dat je response time 180 milliseconden is (p95), je throughput 450 verzoeken per seconde, je error rate 0,2%, je CPU op 65% en je geheugen stabiel op 4,2 gigabyte. Alle vijf groen: dit systeem is klaar voor productie.
Maar stel nu dat dezelfde test andere resultaten geeft: response time 150 milliseconden, throughput 480 verzoeken per seconde, error rate 0%, maar CPU op 95% en geheugen dat groeit van 3 naar 5 gigabyte. De eerste drie metrics zien er perfect uit, en toch is dit systeem niet klaar omdat CPU en geheugen het echte verhaal vertellen: dit gaat crashen, niet vandaag misschien maar binnenkort wel. Zonder die twee metrics had je dat nooit geweten.
Dat is precies waarom je bij performance testing alle vijf nodig hebt, want response time alleen is onvolledig. Pas als je het totaalplaatje ziet kun je met vertrouwen zeggen: dit systeem is klaar voor productie.
Wat je morgen anders kunt doen
Je hoeft niet alles in een keer perfect te hebben. Begin bij je eerstvolgende release met het meten van alle vijf de metrics, ook al stel je de targets in het begin wat ruimer in. Het belangrijkste is dat je een compleet beeld krijgt, in plaats van alleen naar response time te kijken en te hopen dat de rest ook goed zit.
Want een performance crash voorkomen begint niet met dure tooling of complexe testplannen. Het begint met goede performance testing en de juiste dingen meten. En nu weet je welke dat zijn.
Wil je sparren over hoe je performance testing het beste aanpakt voor jouw situatie? We denken graag vrijblijvend met je mee.