Grafana k6: Modern Load Testing for Developers and DevOps
Grafana k6 is a modern, open-source load testing tool designed for developers and DevOps engineers. It focuses on performance, automation, and developer experience. k6 is written in Go and allows you to write test scripts in JavaScript (ES6). This makes it accessible to developers who are already familiar with JavaScript, and it integrates well into CI/CD pipelines for automated performance testing.
Key Features
- Scripting in JavaScript: Test scripts are written in ES6 JavaScript, making it easy for developers to adopt.
- Developer-Friendly: Designed with developers in mind, offering a simple and intuitive API.
- Performance Focused: Written in Go for high performance, capable of generating significant load with minimal resources.
- Automation Ready: Integrates easily into CI/CD pipelines for automated performance testing. Can be controlled via CLI and integrates with various monitoring tools.
- Real-Time Metrics: Provides real-time metrics and results, which can be streamed to various backends like Grafana, InfluxDB, and more.
- Extensible: Supports extensions to add custom functionality and protocols.
- Cloud Execution: k6 Cloud provides a platform for running tests from multiple locations around the world, simulating real-world user scenarios.
Use Cases
- Load Testing: Simulating a large number of users to assess the performance of a system under heavy load.
- Stress Testing: Pushing a system beyond its limits to identify breaking points and failure modes.
- Soak Testing: Testing a system's stability over a long period of time.
- Performance Monitoring: Integrating performance tests into CI/CD pipelines for continuous performance monitoring.
- API Testing: Evaluating the performance and reliability of APIs.
- Integration Testing: Ensuring the performance of integrated systems and microservices.
Getting Started
Installation
macOS (using Homebrew)
brew install k6
Linux
You can install k6 using package managers like apt
(Debian/Ubuntu), yum
(CentOS/RHEL), or apk
(Alpine). Refer to the official k6 documentation for specific instructions for your distribution.
Docker
docker pull grafana/k6
Writing a Simple Test Script
Create a JavaScript file (e.g., script.js
) with your test logic. Here's a basic example:
import http from "k6/http";
import { sleep } from "k6";
export const options = {
vus: 10, // Virtual Users
duration: "30s", // Test duration
};
export default function () {
http.get("http://localhost/");
sleep(1); // Sleep for 1 second between iterations
}
Running the Test
Run the test using the k6 run
command:
k6 run script.js
This will execute the test script, simulating 10 virtual users making requests to http://localhost/
for 30 seconds.
Core Concepts
- Virtual Users (VUs): Simulate concurrent users accessing the system.
- Iterations: Each VU executes the
default
function multiple times during the test. - Options: Configuration settings for the test, such as the number of VUs, duration, and thresholds.
- Metrics: k6 collects various metrics during the test, such as response times, request rates, and error rates.
- Thresholds: Define performance goals and automatically fail the test if they are not met.
Important Options and Configuration
vus
: The number of virtual users to simulate.duration
: The duration of the test (e.g.,'1m'
,'30s'
).iterations
: The number of iterations each VU should perform (use either duration or iterations, not both).rps
: The maximum requests per second to allow. Useful for controlling load and avoiding overwhelming the system.stages
: Define complex load profiles using multiple stages with varying VUs and durations (see examples below).thresholds
: Define acceptance criteria for the test.scenarios
: Group related test logic and configurations into reusable scenarios.
Stages Example
export const options = {
stages: [
{ duration: "10s", target: 10 }, // Ramp up to 10 VUs over 10s
{ duration: "20s", target: 10 }, // Stay at 10 VUs for 20s
{ duration: "10s", target: 0 }, // Ramp down to 0 VUs over 10s
],
};
Thresholds Example
export const options = {
thresholds: {
http_req_duration: ["p95<200ms", "avg<150ms"], // 95th percentile < 200ms, average < 150ms
http_req_failed: ["rate<0.01"], // Less than 1% of requests should fail
},
};
Advanced Usage
- Modularizing Tests: Split test logic into multiple modules for better organization and reusability.
- Data Parameterization: Use data from CSV files or other sources to drive test cases.
- Custom Metrics: Create custom metrics to track specific aspects of the system.
- Integrations: Stream metrics to various backends like Grafana, InfluxDB, Datadog, and others.
Examples
-
Basic Load Test:
import http from "k6/http";
import { sleep } from "k6";
export const options = {
vus: 50,
duration: "1m",
};
export default function () {
http.get("http://localhost/");
sleep(1);
} -
Test with Ramp-Up Stages:
import http from "k6/http";
import { sleep } from "k6";
export const options = {
stages: [
{ duration: "30s", target: 20 }, // Ramp up to 20 VUs over 30s
{ duration: "1m", target: 20 }, // Stay at 20 VUs for 1m
{ duration: "30s", target: 0 }, // Ramp down to 0 VUs over 30s
],
};
export default function () {
http.get("http://localhost/");
sleep(1);
} -
Test with Thresholds:
import http from "k6/http";
import { sleep } from "k6";
export const options = {
vus: 10,
duration: "30s",
thresholds: {
http_req_duration: ["p95<200ms"],
http_req_failed: ["rate<0.01"],
},
};
export default function () {
const res = http.get("http://localhost/");
sleep(1);
} -
Using Response Data
import http from "k6/http";
import { check, sleep } from "k6";
export const options = {
vus: 10,
duration: "30s",
};
export default function () {
const res = http.get("http://localhost/");
check(res, {
"status is 200": (r) => r.status === 200,
"body size is less than 10KB": (r) => r.body.length < 10000,
});
sleep(1);
} -
Sending a POST request
import http from "k6/http";
import { sleep } from "k6";
export const options = {
vus: 10,
duration: "30s",
};
export default function () {
const payload = JSON.stringify({
name: "k6",
value: 123,
});
const params = {
headers: {
"Content-Type": "application/json",
},
};
http.post("http://localhost/api/endpoint", payload, params);
sleep(1);
}
Considerations
- Resource Intensive: Generating high load can be resource-intensive. Ensure your testing environment can handle the load generated by k6.
- JavaScript Dependency: Requires familiarity with JavaScript for writing test scripts.
Summary
Grafana k6 is a powerful and developer-friendly load testing tool that integrates well into modern development workflows. Its JavaScript scripting, real-time metrics, and automation capabilities make it an excellent choice for performance testing and monitoring. Its cloud execution platform allows running tests that simulate geo-distributed traffic.