Load Testing Patterns: Ramp, Spike, Soak, Stress, and Arrival Rate
Short answer
A load testing pattern is how concurrency changes over time—not just “how many users.” The usual set is ramp (climb to a plateau), spike (sudden jump and recover), soak (hold realistic load for a long time), and stress (push past expected demand until the system breaks). Combined with a closed (fixed VUs) vs open (arrival rate) model and think time, the pattern decides whether your k6 chart represents shoppers or a synthetic hammer. TestChimp authors ramping VUs + think time journeys by default and stores the profile name as a comparison key so you never overlay a soak on a spike and call it a regression.
Part of Performance testing guides.
Who this is for
Teams past “we ran k6 once” who need to pick which executor and stages match the business question—flash sale, overnight batch, weekend traffic, or “what is our breaking point?”
Pattern cheat sheet
| Pattern | Shape over time | Business question | Typical k6 executor |
|---|---|---|---|
| Smoke | 1 VU, short | Does the script even work? | shared-iterations / 1 VU |
| Load (ramp + plateau) | Climb, hold expected N, ramp down | Can we serve expected concurrent demand? | ramping-vus |
| Spike | Steep rise, short peak, recover | Do we shed load and recover, or stay wedged? | ramping-vus with aggressive stages |
| Soak (endurance) | Long plateau at realistic N | Memory leaks, queue backup, connection rot? | ramping-vus or constant-vus, long duration |
| Stress | Keep climbing past expected N | Where do we break, and how does it fail (5xx vs timeouts)? | ramping-vus / ramping-arrival-rate past SLO |
| Open-model arrival | N new starts / second regardless of slowness | Can we absorb a marketing burst that does not wait? | constant-arrival-rate / ramping-arrival-rate |
Load testing is the family. These are the waveforms. Volume testing is a different family (dataset size).
Closed model vs open model
Closed model (VUs): a pool of virtual users loops the journey. If the system slows down, each VU spends longer in a request, so completed iterations drop. The system accidentally “protects” the test from seeing a worse arrival rate.
Open model (arrival rate): k6 starts N new iterations per time unit even if previous ones are still running. Slow systems pile up in-flight work—the way a real checkout queue does when people keep arriving.
Use closed + think time when you mean “50 concurrent shoppers who wait between clicks.” Use open when you mean “20 checkouts start every second whether or not the last one finished.” Mixing them without documenting the profile makes run comparison meaningless.
TestChimp’s documented load default is closed-model ramping VUs from a low start, plus think time—because that matches “N users completing the journey,” not a flood of naked HTTP.
Think time
Think time is a paced sleep between journey steps (browse, change quantity, confirm). Without it:
- 20 VUs can generate more RPS than 200 real people
- You overfit to CPU-bound request handling and under-test sessions, caches, and lock time
Put think time in the journey, not by shrinking the VU count and hoping. Changing think time or mock latency is a new comparison key in TestChimp (mock/latency profile)—do not treat a 0 ms stub as the same test as a 200 ms payments double.
Ramp (the default load pattern)
Start at 0–few VUs, climb, hold, climb down. Why:
- You can see when p95 or 5xx broke relative to VU count
- A flat VU chart + exploding p95 means you never actually ramped (env, seed, or script)—a first-class read of Executions charts
stages: [
{ duration: '2m', target: 10 },
{ duration: '10m', target: 10 },
{ duration: '2m', target: 0 },
];
Spike
Model flash sales, app-store features, or a celebrity link:
- Low baseline
- Near-instant climb to a high target
- Short hold
- Return to baseline — watch recovery (queues draining, error rates returning)
A spike that never recovers is often worse than a high plateau that stays within SLO. Overlay failed request rate with 5xx vs 4xx: a 503 storm is shed load; a 429/422 storm may be your rate limiter working as designed.
Soak (endurance)
Hold expected load for hours (policy-defined). Catches:
- Memory leaks and unbounded caches
- Connection pool exhaustion that only appears after many iterations
- Disk / log / queue growth
- GC pauses that a 10-minute load run misses
Soak is still load, not volume. Pair a soak with a mature dataset only when you intentionally run a second, separately named profile—do not silently enlarge the DB mid-soak.
Stress
Stress testing is not “load testing but bigger numbers in Slack.” It is a deliberate climb past the approved capacity to learn:
- At what VU / arrival p95 and 5xx leave SLO
- Whether failure is graceful (429, degrade reads) or cascading (thread starvation, 5xx storms)
- What to put on the runbook (scale rule, kill switch, cache)
Stress results are incomparable to load-profile baselines. Store them under a stress profile name so TestChimp will not recommend them as the overlay for a release load gate.
Composites (mixed journeys)
Production is never one URL. A composite is a weighted mix of journeys (checkout 40%, browse 50%, account 10%). That answers “can the system handle a typical evening,” not “did this path get slower.”
In TestChimp, adding a journey to a composite needs explicit membership approval. Membership is not permission to raise VUs. Isolated journeys remain the default after a PR; composites belong on release / nightly load. Product: journeys vs composites.
How TestChimp keeps patterns comparable
The wrapper records profile name, dataset, environment, LLM mode, and mock/latency inventory. Recommended comparison runs only list matches. Overlaying a spike on a soak is allowed as Other (directional only).
Release-scoped /testchimp run-perf-tests executes the related journeys for the git range with the approved profile—not an ad-hoc stage list an agent invented.
Related
- What is load testing? · Metrics (p95, 4xx, 5xx) · k6 vs JMeter vs Locust
- k6 organization · Viewing results
Frequently asked questions
What are the main load testing patterns?
Ramp-and-plateau (expected load), spike (sudden burst and recover), soak (long endurance at realistic load), and stress (past expected demand to find the breaking point). Choose a closed (VU) or open (arrival-rate) model and include think time so the pattern matches real users.
What is the difference between spike testing and stress testing?
Spike testing jumps to a high concurrent load for a short time and then returns to baseline to test recovery. Stress testing steadily exceeds expected capacity to find where and how the system fails. A spike can be below or above the usual load; stress is defined by going past it.
What is soak testing?
Soak (endurance) testing holds a realistic load for a long duration to find leaks, queue backup, and resource rot that short load tests miss. It is not the same as volume testing, which is about how much data already exists.
Should I use ramping VUs or arrival rate in k6?
Use ramping-vus (closed model) when you mean N concurrent users completing a journey with think time. Use constant- or ramping-arrival-rate (open model) when new work must keep arriving even if the system is slow. Do not compare the two as if they were the same profile.
How does TestChimp handle load patterns?
Profiles (smoke, load, volume, or a named spike/soak) are comparison keys. Default authoring is ramping VUs plus think time. Executions only recommends overlays that share profile, dataset, environment, and mock latency so a soak is never treated as the baseline for a spike.
Pick a pattern you can compare next week
Keep load, spike, and soak as named k6 profiles. TestChimp ingests the profile with the git SHA so the next release overlay is apples-to-apples.