Load and stress testing with k6
Tags: k6, testing, node
Published: 2024-05-10 20:47:17

---
title: Load and stress testing with k6
published: true
tags: ['k6', 'testing', 'node']
canonical_url: https://sevic.dev/notes/load-stress-testing-k6/
---

[k6](https://k6.io) is a performance testing tool. This post explains types of performance testing and dives into `k6` usage, from configuration to running tests.

### Load and stress testing

Load and stress testing are two types of performance testing used to evaluate how well a system performs under various conditions.

Load testing determines how the system performs under expected user loads. The purpose is to identify performance bottlenecks.

Stress testing assesses how the system performs when loads are heavier than usual. The purpose is to find the limit at which the system fails and to observe how it recovers from such failures.

### Prerequisites

- [k6](https://k6.io) installed

- Script (Node.js) file with configuration and execution function

### Configuration

Configuration is stored inside `options` variable, which allows you to set up different testing scenarios:

- constant user load, the number of virtual users (vus) remains constant throughout the test period

```js
export const options = {
  vus: 30,
  duration: '10m'
};
```

- variable user load, the number of users increases and decreases over time

```js
export const options = {
  stages: [
    {
      duration: '1m',
      target: 30
    },
    {
      duration: '10m',
      target: 30
    },
    {
      duration: '5m',
      target: 0
    }
  ]
};
```

Environment variables can be passed through the command line and are accessible within the script via the `__ENV` object.

```bash
k6 -e TOKEN=token run script.js
```

### Execution function

This function defines what virtual users will do during the test. This function is called for each virtual user and typically includes steps that simulate user actions on the app.

```js
export default function() {
  http.get(URL);
  // Add more actions as required
}
```

### Test report

`k6` generates a report that provides detailed insights into various benchmarks, such as the number of virtual users, requests per second, request durations and error rates.

### Example

This example utilizes `k6` to conduct a load test using a variable user load approach:

- User simulation: The script ramps up to 1,000 users, maintains that level to simulate sustained traffic, and gradually reduces to zero.

- Request handling: During the test, each virtual user sends a POST request to an API, with pauses between requests to mimic real user behavior.

- Performance insights: After the test, k6 provides a report that shows key information, such as how fast the app responds and how many requests fail.

Run it via `k6 -e TOKEN=1234 run script.js` command.

```js
// script.js
import { check, sleep } from 'k6';
import { scenario } from 'k6/execution';
import http from 'k6/http';

export const options = {
  stages: [
    // Ramp up to 1000 users over 10 minutes
    {
      duration: '10m',
      target: 1000
    },
    // Hold 1000 users for 30 minutes
    {
      duration: '30m',
      target: 1000
    },
    // Ramp down to 0 users over 5 minutes
    {
      duration: '5m',
      target: 0
    }
  ]
};

export default () => {
  const response = http.post(
    URL,
    JSON.stringify({
      iteration: scenario.iterationInTest
    }),
    {
      headers: {
        Authorization: __ENV.TOKEN,
        'Content-Type': 'application/json'
      }
    }
  );

  check(response, {
    'response status was 200': (res) => res.status === 200
  });

  sleep(1);
};
```

The demo with the mentioned example is available [here](https://sevic.dev/demos).