Template

Load Test Report Template

Updated October 27, 2026•10 min read•Reporting•Template

Written by

Reviewed by the LoadTester editorial team. Review process: see the editorial policy.

Published
2026-10-27
Last reviewed
2026-10-27
Author
Kristian Razum
Load test report page with a pass-with-conditions verdict, a results versus thresholds table and a latency chart

A load test report should let a reader make a decision in 30 seconds and audit it in 10 minutes. Put the verdict first (pass, fail or pass with conditions, at what load), then the test configuration, a results-vs-thresholds table, the handful of charts that prove it, the bottlenecks found with evidence, recommendations with owners, and raw data in an appendix. Below is each section with a filled-in example for a fictional service, followed by a blank Markdown template you can copy.

About the example

"Larkspur Search API" is a fictional service. Every number in the example sections is illustrative, chosen to show how a section should read. None of it is a benchmark of any real system.

Report vs plan: what this document is for

The load test plan is written before the test and says what you will do and what counts as a pass. The report is written after and says what happened, whether it passed, why, and what to do next. The report should reference the plan rather than repeat it.

Load test planLoad test report
WrittenBefore the testWithin a day or two after
Main readerEngineers running the test, approversDecision makers, then engineers fixing issues
Core contentWorkload model, thresholds, environment, risksVerdict, measured results, bottlenecks, actions
NumbersTargets and forecastsMeasurements, with run IDs and time windows
Ends withSign-off to runRecommendations with owners and a re-test date

Report structure at a glance

#SectionQuestion it answersTypical length
1Summary and verdictCan we ship / handle the event, and at what load?One paragraph
2Test configurationWhat exactly was tested, how?One table
3Results vs thresholdsWhich criteria passed and failed?One table
4ChartsWhere is the evidence?3 to 5 charts
5Bottlenecks foundWhat limits capacity, and how do we know?One short block each
6RecommendationsWhat do we do, who does it, by when?One table
7AppendixCan someone reproduce or audit this?As long as needed

1. Summary and verdict

Write this last, put it first. It needs five things: the verdict, the load it applies to, the headline numbers against target, the main risk, and the decision you are asking for. Avoid "the system performed well"; give the numbers.

Example:

Verdict: PASS WITH CONDITIONS at 600 RPS. Larkspur Search API met all thresholds at the 600 RPS target (forecast peak 400 RPS × 1.5): p95 240 ms (target < 300 ms), p99 690 ms (< 800 ms), errors 0.08% (< 0.5%). Capacity ends at about 700 RPS, where search-cluster CPU saturates and p95 exceeds 1 second. Risk: a peak 75% above forecast degrades search sharply. Condition: add one search node and raise the app pool limit before the 14 November launch (owners below), then re-test at 800 RPS.

Verdict wording should be one of three fixed values, so reports are comparable over time: PASS, FAIL, or PASS WITH CONDITIONS. If you use the third, the conditions must be specific actions with owners.

2. Test configuration

Enough detail for someone to re-run the same test, and to judge whether the environment matches production. Link the plan for the reasoning; record here what actually ran, including deviations.

ItemExample value
Plan referenceLarkspur load test plan v1.2
Build / versionsearch-api 3.8.0 (commit a1b2c3d)
EnvironmentStaging, production-sized: 6 app pods (2 vCPU each), 3-node search cluster, same instance types as production
DataProduction index snapshot, 41 M documents; query list sampled from 7 days of logs
Workload modelOpen (arrival rate). Mix: 70% search, 20% autocomplete, 10% document fetch
Load profileSteps of 200, 400, 600, 800 RPS, 5 min each, 1-min ramps; warmup 2 min at 100 RPS excluded
Thresholdsp95 < 300 ms, p99 < 800 ms, error rate < 0.5%, per step
Run date and window2026-10-21, 14:00–14:28 UTC
Deviations from planSoak test postponed; recommendation cache disabled by a config error in the first run (run discarded, see appendix)

The "deviations" row matters. A report that silently differs from its plan is how wrong conclusions survive review.

3. Results vs thresholds

One row per load level (or per scenario), one column per threshold, and a clear pass/fail per cell. Use steady-state windows only; exclude ramps and warmup, and say so in the table caption.

Example (steady-state minutes of each step, warmup excluded):

StepAchieved RPSp50p95 (< 300 ms)p99 (< 800 ms)Errors (< 0.5%)Result
200 RPS20048 ms110 ms260 ms0.01%PASS
400 RPS40055 ms150 ms380 ms0.02%PASS
600 RPS (target)59971 ms240 ms690 ms0.08%PASS
800 RPS742520 ms1,450 ms3,900 ms2.3%FAIL

Always show achieved RPS next to target RPS. At the 800 RPS step the system only absorbed 742, which is itself a capacity signal, and a sign that a closed-model test would have hidden the problem. The guide to reading load test results covers what to look for in each column.

If you track a single summary number for stakeholders, Apdex is a common choice; compute it with the Apdex calculator and state T next to it.

4. Charts to include

Include charts that prove the table, not every chart the tool produces. Every chart needs the same time axis, the step boundaries marked, and a one-line caption saying what to notice.

  1. RPS over time, target vs achieved. Shows the load was actually applied. Caption example: "Achieved RPS tracks target to 600, flattens at about 740 in the 800 step."
  2. Latency percentiles over time (p50, p95, p99). The core evidence. Mark the thresholds as horizontal lines. Caption: "p95 crosses 300 ms 40 seconds into the 800 RPS step."
  3. Error rate over time, split by status code. 5xx vs timeouts vs 429 tell different stories.
  4. The saturated resource. Whatever the bottleneck section names: CPU of the search nodes, connection pool pending count, queue depth. Same time axis.
  5. Comparison with the baseline run, if one exists: same percentiles for the previous release at the same load. See performance regression testing.

Avoid averages-only latency charts and charts with auto-scaled axes that make a 5 ms change look like a cliff. Charts exported as images should be readable without zooming at the page width the report will be read at.

5. Bottlenecks found

For each bottleneck give the symptom, the evidence, the cause (or best hypothesis, labeled as such) and the impact in load terms. Evidence means a metric and a time, not an impression.

Example, bottleneck 1: search cluster CPU.

  • Symptom: p95 rises from 240 ms to 1,450 ms between the 600 and 800 RPS steps; achieved RPS stalls at 742.
  • Evidence: search node CPU 61% average at 600 RPS, 92–97% from 14:22 UTC in the 800 step; search thread pool queue grows from under 5 to over 400 in the same minute.
  • Cause: the search cluster has no headroom above about 700 RPS with this query mix. Autocomplete queries are 20% of requests but about half of search CPU time (from slow-log sampling).
  • Impact: capacity ceiling about 700 RPS, 17% above target.

Example, bottleneck 2: app connection pool to the search cluster.

  • Symptom: 2.3% errors at 800 RPS, almost all "pool acquire timeout" in app logs.
  • Evidence: pool active at its limit of 20 per pod from 14:22 UTC; pending peaks at 85.
  • Cause: secondary. The pool fills because search calls slow down (bottleneck 1); a larger pool alone would add load to an already saturated cluster.
  • Impact: converts slowness into errors above about 700 RPS.

Distinguish the primary limit from its knock-on effects. Fixing a symptom, such as raising a pool size, without fixing the cause usually moves the failure rather than removing it. The connection pool exhausted guide covers that pattern.

6. Recommendations

Each recommendation needs an owner, a priority tied to the verdict, an expected effect, and how you will verify it. "Optimize queries" is not a recommendation; "cache autocomplete prefixes for 60 seconds, expected to cut search CPU by about a third, verify by re-test at 800 RPS" is.

#ActionPriorityOwnerExpected effectVerify by
R1Add a fourth search nodeBefore launchPlatform teamCeiling from about 700 to about 900 RPSRe-test at 800 RPS
R2Cache autocomplete prefixes for 60 sBefore launchSearch teamLower search CPU per requestRe-test; compare CPU per RPS with this run
R3Return 503 with Retry-After when pool pending > 50, instead of waitingNext sprintAPI teamFail fast under overload, protect latency for admitted requestsStress test above ceiling
R4Run the postponed 2-hour soak at 400 RPSBefore launchQADetect leaks and slow growthSoak report

End the section with the re-test date. A report without one tends to be the last word on the subject until production writes the next one.

7. Appendix

Everything a skeptical reader needs to check your work:

  • Run IDs or links to the raw results for every run, including discarded ones and why they were discarded. In LoadTester, a shareable public result link plus the PDF and CSV exports covers this.
  • Full percentile tables per endpoint, not only the aggregate.
  • The exact test script or scenario definition, and the version of the tool that ran it.
  • Infrastructure configuration at test time: instance counts, autoscaling settings, pool sizes, relevant timeouts.
  • Monitoring dashboard links with the time window pinned.
  • Load generator health: confirmation that the generators were not the bottleneck.
  • Known limitations, such as caches warmer than production or third-party calls stubbed.

Copyable Markdown template

Paste this into your wiki, repository or ticket and replace the brackets. It mirrors the sections above.

# Load Test Report: [service / feature]

Date of test: [YYYY-MM-DD]  |  Author: [name]  |  Plan: [link to plan, version]
Run IDs / result links: [ ... ]

## 1. Summary and verdict
**Verdict: [PASS | FAIL | PASS WITH CONDITIONS] at [N] RPS.**
[Service] [met / did not meet] thresholds at [N] RPS ([forecast] x [headroom]):
p95 [x] ms (target < [y]), p99 [x] ms (< [y]), errors [x]% (< [y]%).
Capacity ends at about [N] RPS, where [resource] saturates.
Risk: [one sentence].
Decision needed / conditions: [actions, owners, date].

## 2. Test configuration
| Item | Value |
|---|---|
| Build / version | [ ] |
| Environment | [size, instance types, differences from prod] |
| Data | [dataset, size, source] |
| Workload model | [open/closed], mix: [endpoint %] |
| Load profile | [steps / ramp / duration], warmup excluded: [ ] |
| Thresholds | [p95, p99, error rate] |
| Run window | [start-end, timezone] |
| Deviations from plan | [ ] |

## 3. Results vs thresholds (steady state, warmup excluded)
| Step | Achieved RPS | p50 | p95 (< [ ]) | p99 (< [ ]) | Errors (< [ ]) | Result |
|---|---|---|---|---|---|---|
| [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [PASS/FAIL] |

Summary metric (optional): Apdex [score] [T = ...]

## 4. Charts
1. RPS target vs achieved - [what to notice]
2. p50/p95/p99 over time with thresholds - [what to notice]
3. Error rate by status code - [what to notice]
4. Saturated resource: [name] - [what to notice]
5. Comparison with baseline run [id] - [what to notice]

## 5. Bottlenecks found
### B1: [name]
- Symptom: [ ]
- Evidence: [metric, value, time]
- Cause: [confirmed | hypothesis] [ ]
- Impact: [capacity ceiling / error onset in RPS]

## 6. Recommendations
| # | Action | Priority | Owner | Expected effect | Verify by |
|---|---|---|---|---|---|
| R1 | [ ] | [ ] | [ ] | [ ] | [ ] |

Re-test date: [YYYY-MM-DD]

## 7. Appendix
- Raw results / exports: [links]
- Per-endpoint percentile tables: [ ]
- Test script / scenario: [link, tool version]
- Infra config at test time: [ ]
- Dashboards (time window pinned): [links]
- Load generator health: [ ]
- Known limitations: [ ]

Before you send the report

  1. The verdict is one of PASS, FAIL or PASS WITH CONDITIONS, and names the load it applies to.
  2. Every number has a unit, and every percentile comes from a steady-state window with warmup excluded.
  3. Achieved RPS is shown next to target RPS at every step.
  4. Each bottleneck has evidence with a metric and a timestamp; hypotheses are labeled as such.
  5. Every recommendation has an owner, a priority and a way to verify it, and there is a re-test date.
  6. Deviations from the plan and discarded runs are listed.
  7. Links to raw results work for the people who will read the report.
  8. If this is a release gate, the result is attached to the release ticket and the baseline for the next regression comparison is updated.

FAQ

What should a load test report include?

A verdict with the load it applies to, the test configuration, a table of results against each threshold per load step, a few charts that prove those results, the bottlenecks found with evidence, recommendations with owners, and an appendix with raw data and run links.

What is the difference between a load test plan and a load test report?

The plan is written before the test and defines scope, workload model, thresholds and environment. The report is written after and records what actually ran, whether it passed, what limited capacity and what to do next. The report should link the plan instead of repeating it.

How long should a load test report be?

The decision part, meaning summary, configuration and results table, should fit on one or two pages. Bottlenecks and recommendations add a page or so. Everything else, such as per-endpoint tables and scripts, belongs in the appendix where it does not slow down the reader.

Which charts belong in a load test report?

Target versus achieved RPS, p50/p95/p99 latency over time with threshold lines, error rate by status code, the saturated resource on the same time axis, and a comparison with the baseline run if there is one. Each chart needs a one-line caption saying what to notice.

How do I write the verdict when some thresholds failed?

Use a fixed vocabulary: PASS, FAIL or PASS WITH CONDITIONS, always with the load level it applies to. If the target load passed but higher steps failed, say where capacity ends and which specific actions, owners and re-test date are the conditions.

Run this as a real load testFree plan: 10 VUs, 50 RPS, live p95/p99 and error charts, no credit card. Starter $19/mo (250 VUs) or Pro $49/mo (2,000 VUs) with a 7-day free trial when you need more.
Start freeCompare plans