Load testing
A load test sends your requests from many simulated users at the same time, and measures how fast the server answers and how often it fails. It answers questions like "does the API stay quick with 50 people using it?".
Only test systems you own or may test
A load test sends a lot of traffic on purpose. Aimed at someone else's server it can slow or break a service that real people depend on, and it may be treated as an attack. Run load tests only against servers you own, or where the owner has given you permission. Prefer a test or staging environment over production, and start small.
Run your first load test
Open the menu of a collection in the sidebar and select Load test collection.
You can also choose Load test folder from a folder's menu, Load test from a request's menu, or Load test (parallel calls)… from the More menu next to Send.
The load tester opens with the title
Load test •and the name of what you chose. Under Requests, untick any request you want to leave out.Start small. Set Parallel users to
5and Iterations / user to10. That is 50 rounds in total.Select Run.
Watch the Results update live. When the run ends, the first line reads
Finished in 4.2s · 50 iterations.
Select Stop to end a run early. No new requests start, and calls already in flight finish first.
Words used on this page
| Word | Meaning |
|---|---|
| Virtual user | One simulated person. Each works through the request list on its own. |
| Round, or iteration | One trip by one user through the request list |
| Call | One request sent and its response |
| Latency | Response time: how long a call took, in milliseconds |
| Throughput | Calls completed per second |
Settings
Everything under Load profile:
| Setting | What it does | Default |
|---|---|---|
| Parallel users | How many virtual users send requests at the same time. Up to 1000. | 5 |
| Iterations / user | How many rounds each user makes. Ignored when a duration is set or Repeat until stopped is on. | 10 |
| Duration (s) | Run for this many seconds instead of a set number of rounds. 0 means use iterations. | 0 |
| Ramp-up (s) | Start the users gradually over this many seconds, so the server warms up. 0 starts everyone together. | 0 |
| Think time (ms) | Pause after each request (after each round in All at once mode), like a person reading a page. | 0 |
| One by one / All at once | How each user works through the requests in a round. See below. | One by one |
| Repeat until stopped | Keep going until you select Stop. Iterations and duration are ignored. | Off |
| Stop iteration on first failure | In One by one mode: when a request fails, skip the rest of that user's round. | On |
| Record request log | Write every call to a file on disk, so you can save the full log when the run ends. | On |
| Save responses | Which response bodies the log keeps: None, Failures only or All. | Failures only |
The helper text under Iterations / user shows the total, for example Total 50 rounds for 5 users and 10 iterations.
One by one or All at once
- One by one: each user sends the requests in order, like a real journey: log in, list orders, pay. Values extracted from one response feed the next request. Use this for flows.
- All at once: each user fires every request at the same moment in each round. There is no order, so nothing can be passed between requests. Use this to hit independent endpoints hard.
Ramp-up example
With 50 users and a ramp-up of 10 seconds, five new users start each second. Without ramp-up, all 50 begin at once, which is harsher on the server and less like real traffic.
Saved responses
Failures only keeps the body of failed calls, so you can read the error messages afterwards. None logs status and timing only and uses the least disk. All keeps every body and uses the most. Each saved body is cut at 64 KB, and a run saves at most 256 MB of bodies.
The request list
Requests (2/3) shows the requests each user sends and how many are ticked. In One by one mode the numbers show the order.
Select Extract values for later requests next to a request to open its Extract (one per line) box. It uses the same syntax as Captures, and starts with the request's own captures:
token = body.data.token
id = data.items[0].idIn One by one mode, later requests in the same round can use the value as {{token}}. A value is extracted only when the call passes.
Variables in a load test
Each virtual user starts with your current variables, plus two extra ones:
| Variable | Value |
|---|---|
{{vu}} | The user's number, starting at 1 |
{{iteration}} | The round number for that user, starting at 1 |
Use them to keep users apart, for example a body of {"email": "user{{vu}}@example.com"}. Extracted values belong to one user and one round. Nothing a load test extracts is saved to your environment.
What counts as a failure
A call passes when all the no-code tests on its request pass. If the request has no tests, it passes when the status is below 400. A call that gets no response fails.
Two differences from the collection runner:
- Scripts do not run in a load test. Use no-code tests and extract rules.
- Calls are not written to the Console, because a load test would flood it.
Read the live results
The first line shows the state: Running · 12.4s · 50 active users · 310 iterations done. Below it, a progress bar shows how far the run has got, by planned calls or by time.
| Tile | Meaning |
|---|---|
| Requests | Total calls made so far |
| Req / sec | Throughput, averaged over the run so far. Higher means the server keeps up. |
| Failed | Calls that failed, and their share of all calls, such as 3 (1.5%) |
| p50 | Half of the calls were faster than this |
| p95 | 95% of the calls were faster than this |
| p99 | 99% of the calls were faster than this |
| Avg | Total time divided by the number of calls |
| Max | The slowest single call |
p50, p95 and p99 for beginners
These are percentiles. Imagine lining up every call from fastest to slowest.
- p50 is the call in the middle. Half were faster, half slower. It is the typical experience, also called the median.
- p95 is near the slow end: 95 of every 100 calls were faster. Only 1 call in 20 took longer. Speed goals are often written against p95.
- p99 shows the rare worst delays: 1 call in 100 was slower than this.
A worked example with 100 calls: 94 take about 100 ms, five take about 400 ms and one takes 2000 ms.
| Number | Value | What it tells you |
|---|---|---|
| p50 | about 100 ms | Most people get a fast answer |
| p95 | about 400 ms | 1 in 20 waits four times as long |
| p99 | about 400 ms | The slow group is consistent |
| Max | 2000 ms | One call was very slow |
| Avg | about 134 ms | Pulled up by the slow calls |
The average hides the slow calls; the percentiles show them. Compare Avg with p50: when the average is much higher, a few very slow calls are dragging it up. Percentiles are rounded for long calls: to 10 ms above one second, and to 100 ms above ten seconds.
The other panels
- Throughput (requests / second): a bar for each second of the run, with Passed and Failed stacked. Point at a bar to see its numbers, such as
t = 12s · 48 requests · 2 failed. A flat chart means steady service; a falling one means the server is struggling. - Per request (latency in ms): the same numbers for each request (Calls, Failed, Avg, p50, p95, p99, Max), plus how often each status code came back, such as
200 ×48, and each connection error with its count. - Request log: every call in order, such as
#12 0.84s u3 · i2 200 95 ms. That is call 12, 0.84 seconds into the run, user 3 in its second round, status 200, 95 ms. A call with no response showsERR. The newest 100 calls are listed; select a row with a page icon to see its saved response.
Save a report
Select Save report in the results and choose a format:
| Format | Contains | Good for |
|---|---|---|
| HTML report (summary + log) | One page with the totals, the per-request table, and the call log and saved responses when recorded | Sharing; opens in any browser |
| CSV log (every call) | One line per call | Spreadsheets |
| JSON (every call + saved responses) | Settings, totals, per-request numbers, every call and saved bodies | Scripts and other tools |
The CSV and JSON formats need Record request log to be on. The file is named after the test and the time, for example load-test-shop-api-2026-10-10-14-30-00.html.
CSV columns:
seq,started_at,offset_ms,vu,iteration,step,request,method,url,status,duration_ms,size_bytes,result,errorWARNING
A report holds the URLs that were called and any saved response bodies, as they were. Check it for tokens and personal data before you share it. Set Save responses to None when bodies may be sensitive.
A sensible way to load test
Make the requests pass on their own first. Send each one, add tests, and run the collection once in the runner.
Run a small test, such as 5 users and 10 iterations, and note the p95. This is your baseline.
Increase the users step by step: 10, 25, 50. Use a ramp-up of a few seconds.
Watch for the point where Failed rises or p95 climbs sharply. That is where the server starts to struggle.
Save a report for each step, so you can compare later.
Your own computer and network also limit a load test. Very high user counts measure your machine as much as the server.
Next steps
- Load testing guide: how to plan a load test and read the results.
- Resilience testing: how an API behaves when things go wrong.
- Flaky payments sample project: an API that fails on purpose, to practise on.