Load Models & Scenarios
A load model describes how traffic arrives over time: ramping, steady state and spikes, expressed either as concurrent virtual users or as arrivals per second. Choosing the wrong model is the most common reason load tests misrepresent production.
What is this?
A load model describes how traffic reaches a system over time: how many users, how quickly they arrive and for how long. It is expressed as executors and stages — ramping up, holding steady, ramping down — or as arrival rates (requests per second) when throughput is the question. Choosing the wrong model is the most common reason load tests misrepresent production.
Why do you need it?
- Production traffic is not steady — it ramps, spikes and follows daily patterns, so a flat model cannot validate capacity.
- Arrival-rate models test throughput limits directly, while VU-based models test concurrency limits — they answer different questions.
- Realistic think time and pacing make the requests per second you generate match what real users actually produce.
- Repeatable models let teams compare runs across versions with a known, versioned workload.
- Modeling peak (e.g. Black Friday) and off-peak separately reveals whether autoscaling reacts fast enough.
Mental model
A busy coffee shop
A load model
The manager cares about both how many customers are in line (concurrent users) and how many drinks are made per hour (throughput). Opening an espresso bar changes the arrival model; adding a second barista changes capacity. Load models capture that same distinction.
How it works
- Pick the model axis: concurrent VUs (users in the system) or arrival rate (requests arriving per second).
- Define phases as stages: ramp-up, steady state and ramp-down, each with a target value.
- Set think time so each VU's request rate matches a realistic user, and pacing for arrival models.
- Run the model against the target and measure whether the system holds SLOs at each phase.
- Store the model with the script so later runs and capacity reviews use the identical workload.
Common load model shapes and the load they create over time.
Key commands
k6 run --scenario vu-based script.jsRun only the VU-based scenario from a multi-scenario script.
k6 run --scenario arrival-based script.jsRun only the arrival-rate scenario to probe raw throughput.
k6 run --vus 0 --stage 1m:100 --duration 3m script.jsCLI shorthand for a one-minute ramp to 100 VUs without editing the script.
k6 inspect script.jsPrint the effective options, including resolved scenarios and executors.
exports: {default: {...}}, options: {scenarios: {...}}k6 run --max-duration 10m script.jsHard cap on run length even if an executor misconfigures its duration.
k6 run --summary-export summary.json script.jsExport a machine-readable summary for comparing models across runs.
Examples
Arrival-rate and VU-based scenarios in k6
import http from "k6/http"import { sleep } from "k6" export const options = { scenarios: { "vu-based": { executor: "ramping-vus", startVUs: 0, stages: [ { duration: "1m", target: 200 }, { duration: "5m", target: 200 }, { duration: "1m", target: 0 }, ], gracefulRampDown: "30s", }, "arrival-based": { executor: "constant-arrival-rate", rate: 100, timeUnit: "1s", duration: "5m", preAllocatedVUs: 50, maxVUs: 200, }, },} export default function () { http.get("https://api.example.com/v1/items") sleep(0.5)}The first scenario keeps 200 concurrent users in the system with a five-minute steady state; the second sustains 100 requests per second regardless of how fast responses return. Running both answers two different questions: can we serve 200 simultaneous users, and can we sustain 100 RPS?
In production
- Peak-day models (e.g. Black Friday ramps) run in staging weeks before an event to validate autoscaling.
- Arrival-rate models set throughput budgets for API gateways and are reused in charge-back capacity planning.
- Modeled workloads feed soak tests so the request mix matches production read/write ratios.
- Versioned load models are the contract between the performance team and the platform team for shared capacity.
Best practices
- Match the model to the question: VUs for concurrency limits, arrival rate for throughput limits.
- Include realistic think time and a representative request mix rather than one hot endpoint.
- Record the model in the script so everyone can read the intended shape.
- Ramp slowly enough to observe degradation points instead of blasting straight to the peak.
- Re-run the same model after infrastructure changes to attribute changes to the app or the platform.
Common mistakes
- Using a steady flat load for everything, missing the spikes and soak phases production really has.
- Confusing VUs with RPS — 200 VUs with 1s think time is about 200 RPS, but without think time it is many times more.
- Ramping too fast to observe where the system starts to degrade.
- Forgetting gracefulRampDown, so VUs are cut mid-request and the final stage pollutes the summary.
Common issues
insufficient VUs, reached the maximum number of VUsAn arrival-rate scenario ran out of preallocated VUs to keep up with the target rate.
Raise preAllocatedVUs and maxVUs in the scenario options.
the threshold 'http_req_duration' failed 50.00% of the timeLoad exceeded capacity partway through the model, typically during the spike stage.
Split results by stage with tags or identify the ramp point where latency crossed the budget.
script.js: executor 'ramping-vus' does not accept 'rate'Options from one executor were pasted into another.
Use each executor's documented options: stages for ramping-vus; rate and timeUnit for arrival executors.
Debugging tips
- Plot vus and http_reqs over time — a flat vus line with climbing latency means saturation, not a traffic problem.
- Compare RPS achieved vs target in arrival models; a shortfall means the system can't keep up, not a script bug.
- Use --summary-export to see exactly when thresholds started failing per stage.
- Look at iteration rate rather than raw counts when think time changes between runs.
Interview checkpoint
Hands-on lab
- Generate a synthetic hourly request pattern from an access log
- Translate the pattern into a ramping load model
- Run the VU-based model and read the peak concurrency
- Add an arrival-rate scenario and compare the two perspectives
Model Production Traffic from an Access Log
35 min · intermediate
Quick quiz
Which executor is best when the goal is to sustain exactly 500 requests per second?
In k6, 100 VUs always generate exactly 100 requests per second.
A system degrades only when traffic jumps quickly. Which stage shape best exposes this weakness?
Cheat sheet
ramping-vusRamp users over stagesconstant-vusFixed concurrent usersconstant-arrival-rateFixed RPS — throughput testramping-arrival-rateScale RPS over stagesstages: [1m:100, 5m:100, 1m:0]Ramp, hold, ramp-downgracefulRampDownLet in-flight requests finish