Performance and Load Test Tools
ApacheBenc (ab
)
locust
Python-based load testing
K6
JS-based load testing
Installation
$ sudo gpg -k
$ sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69echo "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:
$ k6 run test.js
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 iterationsdefault ✓ [======================================] 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, });}