What Is Load Testing?
Load testing evaluates how a software system behaves under a specified workload. For an HTTP API, that means sending a representative mix of requests and measuring response times, errors, throughput and resource use against defined criteria. The question is concrete: can this version of the application handle the workload you expect?
This guide covers software, websites and APIs. A useful test specifies the traffic, environment, data and measurement window; “simulate lots of users” is not enough. Results can expose a slow endpoint, a saturated connection pool or a regression after a change. They provide evidence for an engineering decision, not a guarantee against outages.
Define the workload before choosing a user count
Load can describe several different quantities. Keep their units separate:
| Quantity | What it describes | What else you need |
|---|---|---|
| Requests per second (RPS) | HTTP requests attempted, received or completed per second | Which count, endpoint mix and observation window |
| Concurrent virtual users (VUs) | Simulated workers executing a user scenario | Requests per iteration, response times and pauses |
| Concurrent in-flight requests | Requests awaiting completion at a particular moment | Request duration and arrival pattern |
| Business transactions per second | Completed application operations, such as checkouts | The operation’s success condition and its constituent requests |
A fixed number of VUs does not imply fixed RPS. In a closed workload model, a worker completes an iteration before starting another; slower responses or longer think time between actions reduce its iteration rate. An arrival-rate model schedules new iterations independently of prior completion. One iteration may issue several requests, so iterations per second and RPS can differ. Grafana’s workload-model documentation explains this distinction.
Daily active users do not supply either value directly. Measure the endpoint set and time window you intend to reproduce. When modeling human journeys, include appropriate pauses; when modeling machine-to-machine requests, use the observed arrival pattern.
Use representative traffic and data
Choose a workload that can answer your test question. Include the important routes, methods, payload sizes, query variations and authentication paths. A test containing only a cheap health check says little about a search endpoint with expensive database queries.
Prepare data with relevant volume and variety. Record whether caches are warm, whether repeated requests reuse the same records, and whether a long test changes database size. Keep the environment and dependencies comparable between runs; document differences from production, including resource limits and network conditions.
Use an isolated target with controlled external side effects. Test credentials and application state must make sense there. A realistic request cannot validate a checkout if the target lacks its cart data or unexpectedly sends a real payment.
Load testing and other performance tests
Performance testing is the broader activity. An expected-load test checks a representative operating workload; a stress test evaluates heavier load and recovery; a spike test examines an abrupt change; and a soak or endurance test looks for degradation over time. Capacity testing seeks the highest measured workload that still meets your criteria.
These labels describe different objectives, not universal user counts or durations. A gradual increase is useful for an expected-load trial, while a deliberate abrupt increase belongs in a spike test. See the types of load testing guide for workload shapes and measurements.
Choose metrics and acceptance criteria
Define success before the run. Use criteria that match your service and endpoint, rather than a generic two-second response target.
- Latency: choose the measurement boundary, percentile and time window. Averages can hide slow requests; inspect the distribution and relevant endpoint groups.
- Throughput: compare attempted, received and successful requests. If the generator misses its intended rate, the target has not necessarily been tested at that workload.
- Errors: define which status codes, timeouts and application outcomes count as failures. An expected validation rejection can differ from an unexpected server error.
- Resources: track CPU, memory, connections, queues and database behavior alongside request metrics. Correlation helps form a hypothesis; it does not establish the cause by itself.
Record a stop condition and an owner who can reduce or stop traffic. A test should also check whether the system recovers after load decreases.
Run a controlled API test
Suppose your team wants to check a catalog API after changing a database query. An illustrative plan, not a measured result, might specify:
- Workload: product-list and product-detail requests, with proportions and timing taken from a chosen production window. Include representative search terms and response sizes.
- Environment: the candidate application revision, a documented dataset and fixed resource configuration; external integrations use test services.
- Criteria: the team’s latency and error targets, an intended request rate, resource limits and a recovery check. Fill in the actual values before running.
- Sequence: a small routing/data trial, controlled increases toward the expected workload, a stable observation window, then reduced load. Record achieved traffic at every stage.
- Comparison: run the baseline and candidate with equivalent inputs and conditions; investigate any difference before attributing it to the code change.
Start small enough to verify your setup. For typical-load tests, increasing gradually lets you observe changes before reaching the target workload; it does not remove the need for stop criteria. Grafana’s average-load testing guidance describes this progression. Choose durations for your system’s behavior and test objective, rather than treating an example duration as a standard.
Where GoReplay fits
Synthetic scripts let you specify new journeys, data and assertions. GoReplay supplies another input: captured HTTP requests that you can filter, rewrite and replay. These approaches can complement each other. Replaying requests alone does not verify response correctness, create new user sessions or reproduce every dependency and client behavior.
For a captured workload:
- Choose an authorized plaintext HTTP capture point. Encrypted HTTPS requires access to plaintext after TLS termination; raw capture does not decrypt it.
- Save a fresh sample. When you need one named file, use
--output-file-appendand carry that exact filename into replay. Review sensitive fields and side effects; a GET filter is not sanitization. - Prepare the target’s authentication, data and dependencies, then replay a small sample and check the target’s observations before increasing load.
The record-and-replay walkthrough shows that preparation and application verification. The file guide and HTTPS capture guide explain the capture boundaries.
For example, with an already reviewed requests.gor and a running isolated HTTP target at 127.0.0.1:8081, this command repeats the file for a bounded trial:
gor --input-file "requests.gor|100%" --input-file-loop \
--exit-after 30s --output-http "http://127.0.0.1:8081"
The percentage scales recorded timestamp gaps. It does not promise a particular RPS, smooth traffic or session order. The 30-second limit can interrupt a pass or leave responses unfinished, so measure what reached the target. Use the GoReplay load-testing guide for options and the load-test planner to record your own stages and criteria. This example is not a performance benchmark.
Turn results into a specific change
Save the capture or script version, application revision, environment, data assumptions and measurement windows with the results. If latency rises alongside database queueing, investigate that path, change one relevant variable and repeat the comparison. Scaling hardware, adding instances and changing a query solve different problems; the bottleneck and retest should guide the choice.
Report successful business operations separately from HTTP request counts. More replayed requests do not establish more orders or revenue. A cost-saving claim needs comparable infrastructure cost and service outcomes, not just a higher throughput number.
Repeat useful checks in CI
Run small, repeatable checks for relevant changes and schedule larger load or endurance tests where their duration and environment requirements fit. Keep workload versions, test data and measurement windows stable enough to compare results. Investigate inconsistent runs before turning them into a release gate.
Your test harness must evaluate performance criteria and application behavior; GoReplay’s successful exit alone is not a pass condition. Canary monitoring and production observations can provide additional feedback after deployment, but answer different questions from a controlled load test.