Performance Testing Guide

Test Types

TypeGoalDurationPattern
Smoke TestVerify system works at all under minimal load1-5 min1-5 VUs, normal traffic
Load TestVerify system at expected production load10-30 minRamp to expected concurrent users
Stress TestFind breaking point; what happens above capacity15-60 minRamp up until failure
Spike TestSudden 10x traffic surge behavior5-15 minInstant jump to 10x normal
Soak TestMemory leaks, resource exhaustion over time2-24 hoursSteady load for extended period
Breakpoint TestFind maximum capacity / crash point30-90 minLinearly increase until failure

k6 Load Test Script

import http from 'k6/http'; import { check, sleep } from 'k6'; import { Rate, Trend } from 'k6/metrics'; const errorRate = new Rate('errors'); const loginDuration = new Trend('login_duration'); export const options = { stages: [ { duration: '2m', target: 50 }, // ramp up { duration: '5m', target: 50 }, // steady state { duration: '2m', target: 100 }, // ramp up more { duration: '5m', target: 100 }, // steady state { duration: '2m', target: 0 }, // ramp down ], thresholds: { http_req_duration: ['p(95)<500', 'p(99)<1000'], // 95th pct < 500ms errors: ['rate<0.01'], // error rate < 1% http_req_failed: ['rate<0.01'], }, }; export default function () { // Login const loginRes = http.post('https://api.example.com/auth/login', { email: '[email protected]', password: 'password123', }); loginDuration.add(loginRes.timings.duration); const loginOk = check(loginRes, { 'login status 200': (r) => r.status === 200, 'has token': (r) => r.json('token') !== undefined, }); errorRate.add(!loginOk); const token = loginRes.json('token'); // List users const usersRes = http.get('https://api.example.com/api/users', { headers: { Authorization: `Bearer ${token}` }, }); check(usersRes, { 'users status 200': (r) => r.status === 200 }); sleep(1); // think time }

Key Metrics to Track

MetricTargetWarning
Throughput (RPS)Matches expected peak loadDrops under load → bottleneck
Response time p50< 200ms> 500ms
Response time p95< 500ms> 1000ms
Response time p99< 1000ms> 2000ms
Error rate< 0.1%> 1%
CPU utilization< 70%> 85%
Memory growthStable over timeLinear growth = leak
DB connection poolNot exhaustedWait queue > 0