The four load test types
Each pattern is designed to answer a different question:
| Pattern | Question answered |
|---|---|
| Smoke test | Does the app work at all under minimal load? |
| Load test | Does it meet SLOs at expected production load? |
| Stress / spike test | What happens at 2× or 10× normal load? |
| Soak test | Does it degrade over time under sustained load? |
Smoke test
A quick sanity check — a handful of VUs for a short time.
export const options = {
vus: 3,
duration: '1m',
thresholds: {
http_req_failed: ['rate<0.01'],
},
};
When to run: Every PR, before a deployment, after an incident.
Load test (constant rate)
Simulates steady-state production traffic.
export const options = {
scenarios: {
steady_load: {
executor: 'constant-arrival-rate',
rate: 500, // 500 requests per second
timeUnit: '1s',
duration: '10m',
preAllocatedVUs: 50,
},
},
thresholds: {
http_req_duration: ['p(95)<200'],
http_req_failed: ['rate<0.005'],
},
};
Use constant-arrival-rate instead of constant-vus for meaningful throughput targets — VU-based tests produce variable RPS as latency changes.
Ramp-up test
Gradually increases load to find the breaking point.
export const options = {
stages: [
{ duration: '2m', target: 100 }, // ramp to 100 VUs
{ duration: '5m', target: 100 }, // hold
{ duration: '2m', target: 500 }, // ramp to 500 VUs
{ duration: '5m', target: 500 }, // hold
{ duration: '2m', target: 1000 }, // ramp to 1000 VUs
{ duration: '5m', target: 1000 }, // hold
{ duration: '2m', target: 0 }, // ramp down
],
};
Watch the p99 latency chart. The point where it starts climbing steeply is your practical capacity.
Spike test
An instant jump to 10× normal load — simulates flash sales, news events, bot traffic.
export const options = {
stages: [
{ duration: '30s', target: 50 }, // normal load
{ duration: '10s', target: 5000 }, // SPIKE
{ duration: '3m', target: 5000 }, // hold the spike
{ duration: '10s', target: 50 }, // back to normal
{ duration: '3m', target: 50 }, // recovery check
],
};
Key question: does the service recover after the spike, or does latency stay elevated?
Soak test
24–72 hours at moderate load. Catches memory leaks, connection pool exhaustion, disk fill.
export const options = {
stages: [
{ duration: '5m', target: 200 },
{ duration: '24h', target: 200 }, // hold for 24 hours
{ duration: '5m', target: 0 },
],
thresholds: {
http_req_duration: ['p(99)<1000'], // more lenient SLO for long runs
},
};
Warning: Don't run soak tests against production unless you're certain about the load level.
Combining patterns
A complete test suite typically runs all four:
On every PR: smoke test (3 VUs, 1 min)
Nightly: load test (steady production load, 15 min)
Pre-release: stress test (ramp to 3× production, find breaking point)
Weekly: soak test (production load, 2 hours)
This covers correctness, SLO, capacity, and long-term stability in a single automated pipeline.