Skip to main content

Website Load Testing Made Easy: K6 Install & Setup Guide

·3 mins

If you have a quick google, it can be hard to find a solution that will actually work. You’ll see weird paid-for options, outdated open source projects and generally just get frustrated. Hopefully, what I show here will put an end to that. Don’t be dissuaded by the fact that it uses JavaScript files to run the tests, lots of examples are out there and are super easy to tweak.

Heard of Grafana? Well, K6 are maintained by the same organization, Grafana Labs. Here’s the initial install:

Debian / Ubuntu

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-get install k6

CentOS / RHEL

sudo dnf install https://dl.k6.io/rpm/repo.rpm
sudo dnf install k6

MacOS (Using Homebrew)

brew install k6

Windows (Using Windows Package Manager)

winget install k6

As you can see, it’s a one command setup. You can even run a docker pull grafana/k6 to get it up on Docker.

Simple GET Request Script #

This script will create 100 VU’s (think resources that create requests) over 30 seconds, increase that to 150 in the next 45 seconds, then spend the next minute ramping down.

import http from 'k6/http';
import { sleep, check } from 'k6';
import { Counter } from 'k6/metrics';

// A simple counter for http requests

export const requests = new Counter('http_reqs');

// you can specify stages of your test (ramp up/down patterns) through the options object
// target is the number of VUs you are aiming for

export const options = {
  stages: [
    { target: 100, duration: '30s' },
    { target: 150, duration: '45s' },
    { target: 0, duration: '1m' },
  ],
  thresholds: {
    http_reqs: ['count < 1000'],
  },
};

export default function () {
  // our HTTP request, note that we are saving the response to res, which can be accessed later

  const res = http.get('https://INSERTURLHERE');

  sleep(1);

  const checkRes = check(res, {
    'status is 200': (r) => r.status === 200,
  });
}

You can then run ‘k6 run FILENAME’ and it’ll show quite a nice TUI and a report at the end for how the testing went. This is also a good opportunity to check the resource usage for your web servers. Check out a quick example I can show using Asciinema!

You can view additional setup scripts and documentation on the official k6 docs website

Now, why would you run this over a simple loop script in your language of choice? Simplicity, granularity, and versatility. This is stupidly easy to configure, and even easier to run. All I have to do is use a one-liner every time I want to load-test my new web cluster. Neat, huh?