QA How-To
Designing a load model (2026)
Learn designing a load model for performance tests: open vs closed workloads, traffic mix, think time, duration, gates, and k6/JMeter/Gatling examples.
20 min read | 2,903 words
TL;DR
Designing a load model means defining demand control (open or closed), journey mix, think time, data, duration, and pass criteria from evidence. Implement those parameters in your tool only after the model is reviewable on one page.
Key Takeaways
- A load model starts from a business risk question, not from a VU count.
- Choose open arrival control or closed concurrency from real demand behavior.
- Publish mix weights, think time, data shape, duration, and gates in writing.
- Virtual users are not RPS; estimate from iteration shape or target arrivals directly.
- Map environment capacity honestly when staging is smaller than production.
- Encode thresholds before the run and abort invalid generator-bound tests.
- Review the model when traffic, architecture, or seasons change.
Designing a load model is how performance testers turn business demand into a controlled traffic profile that tools can execute. A load model answers who arrives, how fast they arrive, which journeys they take, how long they stay, and what success looks like. Without that design, teams often confuse "more virtual users" with "more realistic risk" and ship charts that cannot defend a release decision.
This guide is a practical playbook for designing a load model in 2026. You will map production-like demand, choose open or closed workloads, define mixes and think time, set durations and gates, and translate the model into k6, JMeter, or Gatling configuration. The emphasis is evidence and clarity, not vanity concurrency numbers.
TL;DR
| Design question | Model output | Bad substitute |
|---|---|---|
| What business risk are we testing? | Objective statement | "Hit 10k users" |
| How does demand arrive? | Open rate or closed pool | Random VU slider |
| Which journeys matter? | Weighted scenario mix | One mega-script |
| How long do users think? | Pause distribution | Zero think time forever |
| What is pass/fail? | Error + percentile gates | "Looks fine on the graph" |
| How long must we run? | Steady-state duration | 2-minute spike only |
A good load model is a testable hypothesis about demand. The tool script is only the implementation.
1. Designing a Load Model: Start From Risk, Not From Tool Settings
Designing a load model begins with a performance question that stakeholders care about. Examples:
- Can checkout sustain Black Friday arrival rates with p95 under the service objective and error rate under 1%?
- Does search stay healthy when browse traffic triples for thirty minutes?
- Does the API degrade gracefully when a dependency slows?
Write the question, the environment, the protected metrics, and the abort rules before choosing inject functions. Tool syntax comes later. If the question is vague ("make sure it is fast"), the model will be vague and the result will be political.
Separate test types early:
- Smoke load: tiny volume, proves script and environment wiring
- Baseline: moderate representative load for comparison
- Average / peak load: expected normal and busy periods
- Stress: beyond peak to find breaking points
- Spike: sudden arrival change
- Endurance / soak: long duration for leaks and drift
- Breakpoint / capacity: controlled growth to find limits
Each type needs its own model. Reusing a stress profile for a nightly regression usually wastes money or destabilizes shared environments. Stakeholders should be able to read the model title and know which decision the run supports.
2. Designing a Load Model: Gather Evidence for Demand
A load model without evidence becomes fiction. Collect signals from:
- APM and RUM traffic by endpoint or user journey
- API gateway request rates and concurrency
- Product analytics for conversion funnels
- Business calendars (campaigns, payroll windows, market open)
- Capacity forecasts from product and ops
- Previous production incidents
Translate observations into rates and proportions. If production shows roughly 40% browse, 35% search, 20% cart updates, and 5% checkout during peak hour, your model should not be 100% checkout unless checkout isolation is intentional.
Be honest about environment differences. A smaller staging cluster cannot absorb production peak. Either scale the environment, scale the model down with an explicit mapping, or state that the test is comparative rather than absolute certification. For complementary skills, see finding a performance bottleneck and API performance testing tutorial.
When evidence is incomplete, label assumptions clearly. "Assumed 10% checkout because analytics export was unavailable" is honest engineering. Silent guesses become false confidence in release meetings.
3. Open vs Closed Workload Models
This is the most important design choice after the business question.
Open model: control arrivals (users or iterations starting per time unit). Concurrency is an outcome. When the system slows, more users remain in flight. Open models fit web arrivals, public APIs, and event-like demand.
Closed model: control concurrency (active users). Throughput is an outcome. When the system slows, completed iterations fall. Closed models fit fixed worker pools, call-center seat counts, or batch agents with a capped population.
| Attribute | Open | Closed |
|---|---|---|
| Control knob | Arrival rate | Concurrent users |
| When latency rises | Concurrency rises | Throughput falls |
| Good for | Public traffic, marketing spikes | Fixed seats, limited agents |
| Misuse risk | Oversubscribe shared envs | Hide arrival reality |
In k6, arrival-rate executors such as constant-arrival-rate and ramping-arrival-rate express open models, while constant-vus and ramping-vus express closed-style concurrency. In Gatling, prefer injectOpen versus injectClosed intentionally. In JMeter, thread groups approximate closed concurrency unless you design throughput shaping carefully.
Never mix the two philosophies casually inside one scenario without explaining why. Interviewers often probe this distinction because it reveals whether a candidate understands feedback loops between latency and load.
4. Define Virtual Users, Sessions, Transactions, and RPS
Teams overload the word "user." Define terms in the model document:
- Virtual user (VU): an entity executing a scenario
- Session / iteration: one pass through a journey
- Transaction / business operation: a meaningful step (login, add to cart)
- Request: a single HTTP call
- RPS / TPS: requests or transactions per second observed or targeted
A VU that performs five HTTP calls with think time is not "5 RPS." Ten VUs are not automatically ten RPS. Estimate:
approx_request_rate ~= (vus * requests_per_iteration) / average_iteration_duration_seconds
For open models targeting arrival rate of iterations:
iteration_arrival_rate = X per second
expected_in_flight ~= arrival_rate * average_iteration_duration
Publish both the control input and the expected secondary metrics. During the run, compare expected versus observed. Large gaps often mean failed correlation, unexpected redirects, or wrong think time. Pair this math with solid scripting via correlating dynamic values.
Also decide whether login is inside every iteration or amortized. Logging in every loop overstates authentication traffic unless auth capacity is the objective. Session reuse policies belong in the model, not as hidden script accidents.
5. Scenario Mix, Think Time, and Data Shape
A single scenario rarely represents production. Design a mix:
| Scenario | Weight | Notes |
|---|---|---|
| Browse catalog | 40% | Read-heavy, cacheable |
| Search | 30% | Sensitive to query shape |
| Cart mutate | 20% | Write path, inventory checks |
| Checkout | 10% | Critical SLI, stricter gates |
Weights can be percentages of arrivals or of concurrent populations depending on model type. Document the choice.
Think time is not optional decoration. Zero think time turns humans into machines and overstates request rates for the same VU count. Use measured medians when available, or labeled assumptions such as "uniform 1-3s between steps based on product analytics sample." Avoid random sleeps that hide the model from reviewers; prefer explicit distributions your tool supports.
Data shape affects caches and databases as much as arrival rate does. Unique SKUs, repeated SKUs, power-law popular products, localized catalogs, and cold vs warm caches all change outcomes. Designing a load model includes designing data cardinality and account pools. Exhausted accounts and colliding writes are model defects, not only script defects.
If writers create orders, plan cleanup or use isolated tenants so the next run starts from a known state. Residual data can improve or destroy cache realism depending on intent. State the intent.
6. Duration, Ramp, Steady State, and Cool-down
A useful profile usually has phases:
- Ramp-up: grow arrivals or concurrency gradually
- Steady state: hold target long enough for meaningful percentiles
- Optional step-up: additional plateaus for capacity discovery
- Cool-down: reduce load to observe recovery
- Abort rules: stop if errors explode or SLOs burn too fast
How long is long enough? Enough to:
- Pass cold-start effects if you care about them separately
- Gather sufficient samples for p95/p99 stability
- Observe autoscaling reactions if enabled
- For soak tests, cover memory growth and connection leaks over hours
Illustrative k6 open-model sketch:
import http from "k6/http";
import { sleep, check } from "k6";
export const options = {
scenarios: {
peak_browse: {
executor: "ramping-arrival-rate",
startRate: 1,
timeUnit: "1s",
preAllocatedVUs: 50,
maxVUs: 200,
stages: [
{ target: 20, duration: "3m" }, // ramp to 20 iterations/s
{ target: 20, duration: "10m" }, // steady state
{ target: 0, duration: "2m" }, // cool-down
],
exec: "browse",
},
},
thresholds: {
http_req_failed: ["rate<0.01"],
http_req_duration: ["p(95)<500"],
},
};
export function browse() {
const res = http.get(`${__ENV.BASE_URL}/api/catalog?page=1`);
check(res, { "catalog 200": (r) => r.status === 200 });
sleep(1);
}
Thresholds encode the gate part of the model. Do not invent them after seeing a failure. Derive from service objectives and environment mapping. If staging is slower by design, document adjusted gates rather than silently loosening them after a red build.
7. Designing a Load Model: Translate Into Tools
k6
Use scenario executors that match open or closed intent. Prefer arrival-rate executors for public traffic. Use separate scenarios for mix weights with different exec functions and rates. Keep thresholds in source control beside the model doc.
JMeter
Classic thread groups are concurrency-oriented. Throughput shaping timers, precise throughput timers, or custom plugins help approximate arrival rates, but be explicit about limitations. Document whether "200 threads" means 200 concurrent users with think time, not 200 RPS.
Gatling
import {
simulation,
scenario,
rampUsersPerSec,
constantUsersPerSec,
} from "@gatling.io/core";
import { http, status } from "@gatling.io/http";
export default simulation((setUp) => {
const httpProtocol = http.baseUrl("https://api.example.test");
const browse = scenario("Browse")
.exec(http("GET catalog").get("/api/catalog").check(status().is(200)));
setUp(
browse.injectOpen(
rampUsersPerSec(1).to(20).during(180),
constantUsersPerSec(20).during(600)
)
).protocols(httpProtocol);
});
Whatever the tool, store the model parameters as named configuration: target rates, durations, mix weights, gates. Magic numbers buried in scripts rot quickly. See Gatling basics for testers and k6 load testing tutorial for implementation depth.
Validate the translation with a dry run. If the model says 20 iterations/s and the tool delivers 8 because maxVUs is too low, the implementation failed the model. Arrival-rate executors need enough pre-allocated or max VUs to sustain the rate when latency grows.
8. Service Level Indicators, Objectives, and Error Budgets in the Model
Designing a load model without pass criteria is incomplete. Define:
- SLI: the measurement (checkout p95 latency, failed transaction rate)
- SLO / gate: the threshold for this environment and test type
- Scope: global vs critical transaction only
- Minimum sample size: avoid p99 on 40 requests
- Exclusion rules: setup calls, health checks, intentional negatives
Example gate table:
| Transaction | Error rate | Latency gate | Notes |
|---|---|---|---|
| Login | < 0.5% | p95 < 300 ms | Auth dependency |
| Search | < 1% | p95 < 400 ms | Cache sensitive |
| Checkout | < 0.1% | p95 < 800 ms | Business critical |
Also define non-functional abort conditions: generator CPU saturated, network errors from the injector, environment deployment mid-test, or dependency outage outside scope. Those runs are invalid rather than product fails.
Connect gates to who acts on failure. A red checkout p95 might block release, while a yellow cache hit-rate drift might open a ticket without stopping the train. Designing a load model includes designing the decision path.
9. Worked Example: Peak Hour for a Retail API
Business question: Can the retail API hold peak-hour demand on the performance environment mapped to 50% of production peak, with checkout p95 under 800 ms and global HTTP failures under 1%?
Evidence: Production peak approximately 40 iterations/s across journeys; staging sized at half capacity, so target 20 iterations/s total arrivals.
Mix: 40% browse, 30% search, 20% cart, 10% checkout -> 8 / 6 / 4 / 2 iterations per second.
Think time: 1s average between steps inside multi-step scenarios, based on analytics.
Profile: 3 minute ramp, 15 minute steady, 2 minute cool-down.
Data: 5,000 synthetic users, unique carts for writers, popular product set for 70% of views to exercise cache realism.
Monitoring: annotate run in APM; watch API CPU, DB connections, Redis hit rate, checkout error codes.
Invalid if: injector CPU > 85% sustained, or auth provider outside our control is failing.
This example is illustrative, not a universal benchmark. Your numbers must come from your telemetry and architecture. Still, the structure is reusable: question, mapping, mix, profile, data, gates, invalidation rules.
10. Common Model Anti-Patterns and How to Fix Them
- VU vanity: chasing large concurrent users without RPS math -> publish expected request rates
- All write path: 100% checkout destroys data and misrepresents peak -> restore mix
- No ramp: instant max arrival trips safety systems unrealistically for some tests -> use spike tests only when intentional
- Too short: 60 seconds cannot support stable p99 -> extend steady state
- Wrong environment mapping: full production peak on tiny staging -> scale model or environment
- Hidden third parties: hammering analytics or payment sandboxes without approval -> stub or exclude
- Script equals model: no written model, only a script -> add a one-page model doc
- Gates after the fact: thresholds tuned to pass -> freeze gates before the run
- Generator bottleneck ignored: product blamed for injector saturation -> preflight generator health
- One mega-scenario: impossible to attribute which journey degraded -> split scenarios
11. Reviewing and Evolving the Load Model
Models age. Traffic mix shifts after feature launches. New endpoints become hot. Seasonal events redefine peak. Schedule reviews:
- After major incidents
- Before large launches
- Quarterly for evergreen products
- When architecture changes (new cache, new region, new auth)
Keep a changelog: what parameter moved, why, and which run is the new baseline. Comparing last month's stress profile to this month's soak profile is not a fair trend. Designing a load model is ongoing product risk management, not a one-time spreadsheet.
Invite product, SRE, and backend owners into reviews. Performance testers own the method; they should not invent demand numbers in isolation when the business already forecasts campaigns.
12. Documentation Template You Can Copy
Use a short markdown file beside the script:
# Load model: retail API peak
- Question: ...
- Environment: perf-stage (map = 0.5x prod peak)
- Model type: open arrival-rate
- Total target: 20 iterations/s
- Mix: browse 40 / search 30 / cart 20 / checkout 10
- Profile: ramp 3m, steady 15m, cool 2m
- Think time: 1s avg intra-scenario
- Data: 5k users, unique write entities
- Gates: http_req_failed < 1%, checkout p95 < 800ms
- Abort: generator CPU > 85%, auth dependency outage
- Owners: perf-qa@, api-team@
- Last reviewed: 2026-07-01
If the script and the doc disagree, the run is not reviewable. Fix alignment before debating product quality.
13. Coordinating People, Environments, and Generators
Designing a load model is incomplete if only the script exists. Performance runs touch shared databases, caches, message buses, third-party sandboxes, and on-call humans. Before a non-trivial profile:
- Book the environment and announce the window.
- Confirm the build version and feature flags under test.
- Verify synthetic accounts and data refresh strategy.
- Confirm generator capacity with a preflight smoke at low rate.
- Align dashboards and log retention for the run window.
- Name a decision owner for abort and go/no-go.
Multi-generator setups need extra model fields: how traffic splits across injectors, whether clocks are synced for annotations, and how results merge. If two generators each send the full peak, you accidentally doubled demand. The model must state total system arrivals, not per-generator copy-paste rates.
14. From Model to Baseline Library
Once a model works, promote it into a baseline library rather than a one-off experiment. Name baselines by intent (peak-hour-half-prod, checkout-stress, search-soak-4h). Store the model document, script commit, environment topology snapshot, seed data version, result links, and decision notes.
Future tests then answer "did we regress against peak-hour-half-prod?" instead of "is this chart nicer than last time?" Designing a load model becomes an organizational asset when baselines are comparable. Without naming and storage discipline, every run is a snowflake and trends are storytelling.
Interview Questions and Answers
Q: What is a load model in performance testing?
A load model is the designed representation of demand: arrival or concurrency pattern, scenario mix, data, duration, and success criteria. The script implements the model; the model explains why the script's numbers exist.
Q: Open vs closed workload: which do you choose?
I choose open when real demand arrives independently, such as shoppers hitting a site. I choose closed when a fixed population of workers or seats is the constraint. I document the choice because latency feedback differs.
Q: How do you calculate virtual users from RPS?
I do not assume 1 VU equals 1 RPS. I estimate from requests per iteration and iteration duration, or I use arrival-rate executors that target iterations directly and let concurrency emerge.
Q: Why include think time?
Think time models realistic gaps between user actions. Removing it inflates request rates for the same concurrency and can overload systems in ways production would not see for that VU count.
Q: How long should a peak load test run?
Long enough to ramp cleanly, hold steady state for stable percentiles and autoscaling observation, then cool down. Exact minutes depend on metrics and system dynamics; many peak validations need tens of minutes of steady state, while soaks need hours.
Q: What makes a performance gate good?
It is predeclared, tied to user-visible or service-level risk, scoped to the right transactions, and paired with validity checks so generator failures are not blamed on the product.
Q: How do you model a traffic mix?
I split scenarios by business journey with weights from analytics or gateway stats, assign rates or populations accordingly, and keep critical paths measurable on their own.
Common Mistakes
- Starting from a tool's VU slider instead of a business question.
- Treating concurrent users, arrivals, and RPS as interchangeable.
- Using closed concurrency to simulate marketing-driven open arrivals without explanation.
- Omitting scenario mix and over-testing one endpoint.
- Skipping think time and calling the result "realistic user load."
- Running two minutes and declaring p99 trustworthy.
- Copying production peak onto an undersized environment without mapping.
- Leaving payment, email, or analytics third parties in the path without approval.
- Setting thresholds after viewing the report.
- Ignoring data cardinality and cache hit patterns.
- No abort rules when the test itself becomes an incident.
- Comparing unlike profiles and calling it a trend.
- Forgetting that failed scripts invalidate the model results.
- Not documenting owners, environment, and last review date.
- Designing only happy-path reads when writes dominate incident history.
Conclusion
Designing a load model is the skill that turns performance tools into decision systems. Start from risk, gather demand evidence, choose open or closed control correctly, define mix and think time, set duration and gates, then implement the same numbers in k6, JMeter, or Gatling.
Write the one-page model, implement it, run a smoke, then execute the full profile while watching product and generator health. When the model is explicit, debates move from "why 200 users?" to "did we meet the checkout objective under the agreed demand?" That is the standard senior performance testers are hired to uphold.
Interview Questions and Answers
Walk me through how you design a load model.
I start from the risk question and SLIs, gather traffic evidence, choose open or closed control, define scenario mix and think time, size data, set ramp and steady-state duration, predeclare gates and abort rules, then implement the same parameters in the tool.
Explain open versus closed workloads with an example.
An open model might inject 20 checkouts started per second regardless of response time, so concurrency grows if checkout slows. A closed model might keep 50 agents always working tickets, so throughput drops when each ticket takes longer.
How do you avoid confusing VUs with RPS?
I document requests per iteration and average iteration time, or I use arrival-rate executors and report both the control metric and observed RPS. I never claim VU count alone is the performance objective.
How do you set performance pass criteria?
I align gates to service objectives and critical transactions before the run, include error rate and a percentile latency limit, require enough samples, and separate invalid runs caused by the generator or environment.
What is a scenario mix and why does it matter?
A scenario mix allocates demand across journeys such as browse, search, and checkout. A 100% write mix can overload databases and misrepresent peak hour risk, so weights should follow evidence.
How would you model a flash sale spike?
I would define baseline arrivals, a steep ramp or step to the spike rate, a hold window matching the sale physics, cool-down, stricter monitoring, and explicit approval for environment impact. I would not pretend a gentle daily peak model covers spike risk.
What makes a load test result invalid?
Wrong build or environment, broken correlation, saturated load generators, unapproved third-party hammering, insufficient samples for the claimed percentile, or mid-test deployments can invalidate results even if charts look dramatic.
Frequently Asked Questions
What is designing a load model in performance testing?
It is the process of specifying how simulated demand should arrive, which journeys run, how data and think time behave, how long the test lasts, and what pass or fail means. The script is the implementation of that design.
Should I use open or closed workload models?
Use open models when arrivals are independent, such as public web traffic. Use closed models when a fixed number of workers or seats is the real constraint. Document why you chose either approach.
How many virtual users do I need for a load test?
Derive users from the demand model and scenario duration, or target arrival rates directly with open executors. There is no universal VU number that fits every system.
Why does think time matter in a load model?
Think time spaces requests the way real users do. Without it, the same concurrency produces much higher request rates and can create unrealistic pressure.
How long should steady state last?
Long enough for stable percentile estimates, representative caching behavior, and any autoscaling reactions you intend to observe. Many peak tests need many minutes of hold time; soak tests need hours.
Can I run production peak load on staging?
Only if staging capacity and dependencies can absorb it safely. Otherwise scale the model to a documented mapping of production peak, or treat results as comparative rather than absolute certification.
What should a one-page load model include?
Business question, environment mapping, open or closed control, target rates or concurrency, scenario mix, think time, data rules, profile phases, gates, abort conditions, owners, and last review date.
Related Guides
- Load testing: A Complete Guide for QA (2026)
- A/B test validation: A Complete Guide for QA (2026)
- API contract testing with Pact: A Practical Guide (2026)
- API error handling and negative testing: A Practical Guide (2026)
- API idempotency testing: A Practical Guide (2026)
- API pagination testing: A Practical Guide (2026)