API load test scenarios, metrics, and a comparison with k6 and JMeter.
This article explains how to run load tests on APIs — without years of experience — using the open-source tools k6 and JMeter.
- API — an interface that enables communication between applications.
- Load testing — tests that evaluate how an application performs under a given load; they measure resilience, speed, and overall performance.
- k6 — an open-source load-testing tool; JavaScript-based scripts, console-driven. Simulates realistic API traffic and measures how your system responds under load.
- JMeter — an open-source, Java-based load-testing tool; scenarios are defined via GUI or XML. Simulates realistic user behavior.
We'll run the same kinds of tests with both and compare.
Grafana k6 and Apache JMeter compared
| Feature | JMeter | k6 |
|---|---|---|
| Language and style | Java | JavaScript |
| Setup and startup | JRE, GUI-based | Node.js, console-based |
| Performance and scalability | Heavy load tests, higher resource use | Lightweight, scalable |
| Scenario definition | XML, GUI or manual | Code in JavaScript |
| Distributed testing | Broad support | k6 Cloud or custom setups |
| Reporting | GUI, graphs, Grafana / InfluxDB | Console, k6 Cloud, integrations |
| Community | Large user base | Rapidly growing |
JMeter's UI offers graphical reports, backend listener, and Grafana / InfluxDB. k6 is console-based but pairs with many visualization options and Grafana integration.
k6 basic test scenarios
Examples for load, endurance, stress, and performance-optimization scenarios targeting API endpoints.
Load test
Simulates many users connecting at the same time.
import http from 'k6/http';
import { sleep } from 'k6';
export default function () {
const numberOfUsers = 100;
Array.from({ length: numberOfUsers }, (_, index) => {
http.get(`https://example.com/page${index}`);
sleep(1);
});
}
Endurance test
Simulates the application running stably under a constant load for a period.
import http from 'k6/http';
import { sleep } from 'k6';
export default function () {
while (1) {
http.get('https://example.com');
sleep(1);
}
}
Stress test
Simulates sudden traffic spikes or fast changes in user count.
import http from 'k6/http';
import { sleep } from 'k6';
export default function () {
const numberOfUsers = __VU * 10;
Array.from({ length: numberOfUsers }, (_, index) => {
http.get(`https://example.com/page${index}`);
sleep(0.1);
});
}
Example k6 scenario (staged load)
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 500 },
{ duration: '1m', target: 50 },
{ duration: '30s', target: 0 },
],
};
export default function () {
let methods = ['GET', 'POST', 'PUT', 'DELETE'];
let method = methods[Math.floor(Math.random() * methods.length)];
let endpoints = [
'https://example.com/k6_load_test/get',
'https://example.com/k6_load_test/post',
'https://example.com/k6_load_test/put',
'https://example.com/k6_load_test/delete',
];
let endpoint = endpoints[Math.floor(Math.random() * endpoints.length)];
let res = http.request(method, endpoint);
check(res, { 'is status 200': (r) => r.status === 200 });
}
Run with k6 run k6_load_test.js.
Result metrics (summary): http_reqs (total requests),
http_req_duration (response time), http_req_failed, iterations,
vus / vus_max, checks, data_received / data_sent,
p(90) / p(95) (percentiles). These help assess your API's behavior
under load and find bottlenecks. k6 results can be visualized alongside
system metrics via Prometheus and Grafana.
JMeter basic test scenarios
In JMeter you configure Threads (simulated users), Loop count, and Ramp-up Period (time to start all threads).
API performance test. Threads = concurrent requests (e.g. 500); Loop = how many times each user repeats; Ramp-up = time to start all users.
Additional scenarios: (1) increase request count to simulate load, (2) maximum load test, (3) long-duration load test, (4) different request types (GET, POST, PUT, DELETE), (5) average response time test, (6) error-handling test, (7) scheduled tests with a timer.
JMeter can run from the GUI (Run) or from the command line; results can be written to CSV:
jmeter -n -t /path/to/TEST_NAME.jmx -l /path/to/RECORD_NAME.csv
Result metrics (summary): total requests, total time, average requests / second, average / min / max response time, error count and percentage, active / started / finished request counts.
Comparing JMeter and k6 results
| Feature | JMeter | k6 |
|---|---|---|
| Test environment | Standalone test | Local environment |
| Test duration | e.g. 2 min 41 s | e.g. 3 min |
| Target users | e.g. max 500 concurrent | Ramp up to 500 |
| Total requests | e.g. 25,000 | e.g. 180,077 |
| Average response time | e.g. 11.44 s | e.g. 242 ms |
| Max response time | e.g. 21.15 s | e.g. 33.68 s |
| Throughput | e.g. 169.6 req / s | e.g. 857.45 req / s |
Values depend on the example test environment.
Conclusion
JMeter supports high concurrent user counts even at lower throughput and is well suited for large-scale applications. k6 offers higher request throughput and is good for minimizing failed-request rates and for scenarios that require fast responses.
Which tool to use depends on your test requirements, target metrics, and application design. Both can be used in different scenarios and provide valuable data for performance testing.