Load testing is a well-known technique of software testing to make sure, that system we’re working on, behaves in a way, we’d like to. During day-to-day tasks, I started thinking if testing the product only from business perspective is enough. Well… No, so I started some research about it.

I wanted to clarify for myself, what types give me what, as an outcome. What tool should I use, or environment? Do I need to set up something, or just use production? (yeah, jokes aside).

I’ve tested wrk, jmeter, and k6. At the end, the last one looks as the easiest and most configurable one for me. I’ve created a couple of sample scripts, to show you how to use that tool.

In the next article, I’ll explain a bit more about environment, and flow how you can set up your load testing.

Types of load tests

We encounter four types of load tests:

  • Load
  • Stress
  • Soak
  • Spike

Each of them is slightly different, and gives us possibility to check other scenarios/perform quite tests.

Load testing

Being sure, that the system is meeting the performance goals is one of the things, you should pay attention. This kind of test, is the one, which can provide you this answer.

This type is concerned with assessing the current performance in terms of concurrent users or requests per second.

Example code implementation

import { sleep } from "k6";
import http from "k6/http";

export const options = {
  stages: [
    { duration: "5m", target: 100 },
    { duration: "10m", target: 100 },
    { duration: "5m", target: 0 },
  ],
  thresholds: {
    http_req_duration: ["p(99)<250"],
  },
};

export default function () {
  http.get("https://httpbin.test.loadimpact.com/");
  sleep(1); // Make sure, that each user cooldown between requests is 1s
}

Stress testing

The purpose of this type of load test, is to verify the stability and reliability of the system, under extreme condition’s.

Running this type of load test, will:

  • determine behavior of your system under extreme condition’s,
  • determine maximum capacity in terms of users throughput,
  • determine the breaking point of your system,
  • tell you, if your system will recover without manual intervention after the stress test is over.

Example code implementation

import { sleep } from "k6";
import http from "k6/http";

export const options = {
  stages: [
    { duration: "2m", target: 100 },
    { duration: "5m", target: 100 },
    { duration: "2m", target: 200 },
    { duration: "5m", target: 200 },
    { duration: "2m", target: 300 },
    { duration: "5m", target: 300 },
    { duration: "2m", target: 400 },
    { duration: "5m", target: 400 },
    { duration: "10m", target: 0 },
  ],
};

export default function () {
  http.get("https://httpbin.test.loadimpact.com/");
  sleep(1);
}

Soak testing

The purpose of this type of load test, is to validate the system under long-time overload.

Running this type of load test, will:

  • verify that your system doesn’t suffer from bugs or memory leaks,
  • make sure, that your database works under high overload,
  • make sure, that your logs works under high overload,
  • make sure, that external services you depend on, doesn’t stop under high overload.

To run them:

  • determine the maximum number of users your system can handle,
  • get the 80% of that value,
  • run the test in three stages: ramp, stay and cooldown.

Example code implementation

import { sleep } from "k6";
import http from "k6/http";

export const options = {
  stages: [
    { duration: "5m", target: 400 },
    { duration: "3h55m", target: 400 },
    { duration: "5m", target: 0 },
  ],
  thresholds: {
    http_req_duration: ["p(99)<250"],
  },
};

export default function () {
  http.get("https://httpbin.test.loadimpact.com/");
  sleep(1); // Make sure, that each user cooldown between requests is 1s
}

Spike testing

The purpose of this type of load test, is to validate the system under extreme increments and decrements in traffic over a very short time. The main purpose is to evaluate the behaviour of the system to determine recovery time.

Running this type of load test, will:

  • determine how your system will perform under a sudden spikes of traffic,
  • determine if your system will recover.

Example code implementation

import { sleep } from "k6";
import http from "k6/http";

export const options = {
  stages: [
    { duration: "10s", target: 100 },
    { duration: "1m", target: 100 },
    { duration: "10s", target: 1400 },
    { duration: "3m", target: 1400 },
    { duration: "10s", target: 100 },
    { duration: "3m", target: 100 },
    { duration: "10s", target: 0 },
  ],
  thresholds: {
    http_req_duration: ["p(99)<250"],
  },
};

export default function () {
  http.get("https://httpbin.test.loadimpact.com/");
  sleep(1); // Make sure, that each user cooldown between requests is 1s
}

Summary

Load testing is a powerful technique to make sure, that your system behaves as expected in various conditions. My personal feeling is that every project should consider them at some point. Getting more, and more clients can make flood the system, and produce terrible feedback, if it can’t handle them.

k6 seems to be great tool, to set up them fast, clearly with low learning curve.

Sources