Skip to content

Performance and Load Test Tools

ApacheBenc (ab)

locust

Python-based load testing

K6

JS-based load testing

Installation

Terminal window
$ sudo gpg -k
$ sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
$ sudo apt-get update
$ sudo apt install k6 -y

Basic usage

Just create a new ‘.js’ file:

import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
vus: 10, // Virtual Users
duration: '30s', // Test runs for 30 seconds
};
export default function () {
const res = http.get('https://<TARGET_DOMAIN>');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1); // wait 1 second between each request
}

Run:

Terminal window
$ k6 run test.js
Terminal window
k6 run test.js
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | () |
/ __________ \ |_|\_\ \_____/
execution: local
script: test.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
* default: 10 looping VUs for 30s (gracefulStop: 30s)
status is 200
17% 50 / 230
response time < 500ms
checks.........................: 58.92% 330 out of 560
data_received..................: 8.6 MB 281 kB/s
data_sent......................: 45 kB 1.5 kB/s
http_req_blocked...............: avg=21.52ms min=241ns med=1.45µs max=607.88ms p(90)=2.47µs p(95)=3.75µs
http_req_connecting............: avg=1.65ms min=0s med=0s max=47.79ms p(90)=0s p(95)=0s
http_req_duration..............: avg=59.75ms min=35.99ms med=51.4ms max=208.98ms p(90)=88.55ms p(95)=106ms
{ expected_response:true }...: avg=79.35ms min=36.44ms med=57.61ms max=208.98ms p(90)=176.77ms p(95)=183.93ms
http_req_failed................: 82.14% 230 out of 280
http_req_receiving.............: avg=8.08ms min=116.69µs med=4.71ms max=47.73ms p(90)=20.02ms p(95)=23.43ms
http_req_sending...............: avg=213.08µs min=58.44µs med=183µs max=2.8ms p(90)=309.89µs p(95)=368.7µs
http_req_tls_handshaking.......: avg=6.64ms min=0s med=0s max=188.73ms p(90)=0s p(95)=0s
http_req_waiting...............: avg=51.45ms min=31.57ms med=41.78ms max=204.25ms p(90)=71ms p(95)=92.32ms
http_reqs......................: 280 9.13127/s
iteration_duration.............: avg=1.08s min=1.03s med=1.05s max=1.81s p(90)=1.08s p(95)=1.1s
iterations.....................: 280 9.13127/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
running (0m30.7s), 00/10 VUs, 280 complete and 0 interrupted iterations
default [======================================] 10 VUs 30s

Add

export const options = {
stages: [
{ duration: '30s', target: 10 }, // ramp up to 10 users
{ duration: '1m', target: 10 }, // stay at 10 users
{ duration: '30s', target: 0 }, // ramp down
],
};

Add Credentials (username and password)

import http from 'k6/http'
import { check, sleep } from 'k6'
export default function () {
const data = { username: 'username', password: 'password' }
let res = http.post('https://<TARGET_DOMAIN>', data)
check(res, { 'success login': (r) => r.status === 200 })
sleep(0.3)
}

Testing Multiple Endpoints

import http from 'k6/http';
import { check } from 'k6';
export default function () {
const responses = http.batch([
['GET', 'https://<TARGET_DOMAIN_1>'],
[
'POST',
'https://<TARGET_DOMAIN_2>',
JSON.stringify({ username: 'username', password: 'password' }),
{ headers: { 'Content-Type': 'application/json' } },
],
]);
// Validate multiple endpoint responses
check(responses[0], {
'GET request successful': (r) => r.status === 200,
});
check(responses[1], {
'POST login successful': (r) => r.status === 200,
});
}