Skip to content

Designing realistic load

A load test is only as useful as it is realistic. A profile that does not match your production traffic pattern gives you results that are either wrongly reassuring or wrongly alarming. This page shows how to design load profiles that follow the way real users use your system, and what to avoid.

  • Learn the difference between open and closed workload models before you choose your VU or RPS target.
  • Decide if you control virtual users (VUs) or requests per second (RPS). See the ramp-up, think time, and pacing Foundations page.
  • Have at least one production traffic sample (APM trace, access log, or analytics export) to work from.

A realistic load profile has four parts:

  1. Arrival rate / concurrency target: your expected peak, or a defined multiple of it.
  2. Ramp shape: how traffic builds (gradual ramp, sudden spike, step-wise).
  3. Scenario mix: the share of read, write, search and checkout flows.
  4. Think time and pacing: the time real users spend between requests.

Skip any of these and your “load test” becomes a synthetic flood that tells you nothing about how your system behaves under real conditions.

  • Do derive your VU/RPS target from real traffic data. Pull peak RPS from your APM or access logs. If you have no baseline, start with a conservative estimate and run a smoke test first to confirm the setup is correct.

  • Do model scenario mix. If 70 % of your traffic is read-only (product pages, search) and 30 % is write-heavy (checkout, form submission), use that split in your test. In Taurus, use multiple scenarios: blocks with weighted concurrency:

    execution:
    - concurrency: 70
    scenario: browse
    - concurrency: 30
    scenario: checkout
  • Do use a think time that matches human pacing. Add think-time: 1s or use a uniform distribution (uniform(0.5s, 2s)) in Taurus scenarios. With zero think time, each VU sends requests far faster than a person would and saturates your server sooner than real users.

  • Do ramp gradually. A sudden jump from 0 to peak VUs hides warm-up behaviour and caching effects. A ramp-up: 3m gives your server (and its JIT/caches) time to settle before you read steady-state results.

  • Do use multiple MaxoPerf locations when your users are spread across regions. Add locations in the test’s Configuration tab. The run’s Runners tab shows latency per location, so you can spot regional differences.

  • Do test at the load level your failure criteria enforce. If your SLO says p95 < 500 ms at 500 RPS, your test must reach 500 RPS. Set your failure criteria at that level.

  • Don’t use a flat, constant VU count as your only profile. Most real systems see morning ramps, lunch peaks and late-night troughs. A flat test misses the ramp behaviour completely. Pair it with a staged ramp profile.

  • Don’t ignore think time on write-heavy flows. In production, write operations (POST, PUT, DELETE) almost never arrive back-to-back. Without think time between writes, your test hits your database far harder than real usage does.

  • Don’t test a single endpoint in isolation when your system depends on request chains. If your checkout flow triggers downstream calls (inventory, payment, email), a single-endpoint test misses the cascade failures that appear only under combined load.

  • Don’t hardcode a single request body for all VUs. Identical payloads bypass caches and hit the same database rows every time. That creates contention that does not exist in production. Use a CSV data entity to inject realistic variety.

  • Don’t set your target to “as many requests as possible” (max throughput mode) for a standard load test. That is a stress or breakpoint test, not a load test. Know which test type you are running. See Common pitfalls and anti-patterns.

  • Don’t size your runner count on VUs alone. Each MaxoPerf runner has a maximum healthy VU capacity. Put too many VUs on too few runners and the runners become the bottleneck. Your results then show runner saturation, not your system under test. Check the Runners tab during the run.

Traffic typeTaurus patternTypical weight
Read (GET, search, browse)requests: [GET ...]60–80 %
Authenticated read (session-gated)requests: [GET ...] with extracted auth token15–30 %
Write (POST/PUT checkout, form)requests: [POST ...]5–20 %
Heavy write (file upload, batch)requests: [POST ...] with CSV data1–10 %