API load test with K6 (JavaScript + Go)

Hung Tran Nguyen
3 min readJan 17, 2019

Lately while learning load test frameworks alternative to Locust (Python), I found K6 framework (https://k6.io/) which is really amazing and quick to work with.

To install: https://docs.k6.io/docs/installation

What I love the most about K6 is it allows to script with JavaScript which I am familiar with (I am using Jest + Axios to test API). Although there are some limits like I cannot use `npm install` and import node_modules like with nodejs but I can work around with bundling those modules (https://docs.k6.io/docs/modules).

And the core of K6 is Go so the speed of the same test run compared with Locust is quite faster according to my test.

Below is a sample script to test with a signUp API.

import config from '../common/config.js' // I use config.js to export API endpoint variablesimport http from 'k6/http'import { check, sleep } from 'k6'import { Trend } from 'k6/metrics'import faker from 'cdnjs.com/libraries/Faker' // this library is great to generate mock dataexport let SignUpDuration = new Trend('Sign up Duration')
let duration = 1000
export let options = {vus: 10,duration: '30s',thresholds: {'Sign up Duration': [`p(95)<${duration}`]}}export default function () {let res = http.post(__ENV.HOST + config.api.signUp, {"email": 'QA_TECH_' + faker.internet.email(),"password": faker.internet.password(),"language": "vn", "gender": "M"})check(res, {'status is OK': res => res.status == 200,'transaction time is less than threshold': res => res.timings.duration < duration})SignUpDuration.add(res.timings.duration)sleep(1)}

Then run with below command.

k6 run -e HOST=https://www.example.com --vus 5 --duration 10s tests/signUp.js

And K6 outputs nice result to the console.

/\      |‾‾|  /‾‾/  /‾/   
/\ / \ | |_/ / / /
/ \/ \ | | / ‾‾\
/ \ | |‾\ \ | (_) |
/ __________ \ |__| \__\ \___/ .io
execution: local
output: -
script: tests/signUp.js
duration: 10s, iterations: -
vus: 1, max: 1
done [==========================================================] 10s / 10s✗ transaction time is less than threshold
↳ 0% — ✓ 0 / ✗ 2
✓ status is OK
✗ Sign up Duration...........: avg=2816.323819 min=1926.378042 med=2816.323819 max=3706.269597 p(90)=3528.280442 p(95)=3617.275019
checks.....................: 50.00% ✓ 2 ✗ 2
data_received..............: 5.0 kB 504 B/s
data_sent..................: 921 B 92 B/s
http_req_blocked...........: avg=101.78ms min=1.87µs med=101.78ms max=203.57ms p(90)=183.21ms p(95)=193.39ms
http_req_connecting........: avg=34.57ms min=0s med=34.57ms max=69.14ms p(90)=62.22ms p(95)=65.68ms
http_req_duration..........: avg=2.81s min=1.92s med=2.81s max=3.7s p(90)=3.52s p(95)=3.61s
http_req_receiving.........: avg=218.81µs min=195.49µs med=218.81µs max=242.14µs p(90)=237.47µs p(95)=239.8µs
http_req_sending...........: avg=1.64ms min=354.72µs med=1.64ms max=2.93ms p(90)=2.67ms p(95)=2.8ms
http_req_tls_handshaking...: avg=66.86ms min=0s med=66.86ms max=133.73ms p(90)=120.36ms p(95)=127.04ms
http_req_waiting...........: avg=2.81s min=1.92s med=2.81s max=3.7s p(90)=3.52s p(95)=3.61s
http_reqs..................: 2 0.199997/s
iteration_duration.........: avg=3.92s min=3.13s med=3.92s max=4.7s p(90)=4.55s p(95)=4.63s
iterations.................: 2 0.199997/s
vus........................: 1 min=1 max=1
vus_max....................: 1 min=1 max=1
ERRO[0012] some thresholds have failed

Key metrics (https://docs.k6.io/docs/result-metrics)

- **http_reqs**: total requests generated & total request per second (more is better)

- **http_req_duration**: total time for server to process a request and respond completely (less is better)

(equal to http_req_sending + http_req_waiting + http_req_receiving)

- **vus**: number of virtual concurrent users generated

- **iterations**: number of times the VUs executing the script

- **checks**: number of failed checks

Write load test with K6 is really quick and friendly to work. Their API provide useful checks and threshold to test and establish baseline for load test results.

Locust with Python is also nice to work with but now I may find a great alternative to it.

--

--

Hung Tran Nguyen

From translator -> Manual QC Engineer -> Automation QA Engineer -> NodeJS Developer -> yearning to learn more