Blog  /  Engineering

Understanding Grafana k6: A simple guide to the load testing tool

August 10, 2023 5 min

Grafana k6 is a powerful, developer-friendly tool designed and engineered with a focus on load testing — but it boasts capabilities that extend far beyond that use case.

Understanding the inner workings of k6 is helpful to fully leverage its potential, and to tailor the tool to your specific testing needs.

Read on to learn how k6 is structured, and how its underlying design provides the best possible reliability and load testing experience.

Analyzing software under load

Load testing is a software development practice in which testing teams create a controlled environment to mimic different types of loads on their systems — from typical daily usage to extreme conditions that might occur during a major incident. It provides insights into how software behaves under different conditions, helping to identify bottlenecks, uncover performance issues, and ensure the software can handle real-world user demands.

k6 has been engineered with two primary objectives in mind: generating load and collecting measurements, also known as samples, for analysis.

To meet these objectives, k6 enables software teams to describe and refine a testing strategy that accurately reproduces and simulates the traffic and interaction patterns they want to observe. The tool then springs into action, executing the plan and collecting measurements, ultimately empowering users to precisely understand how their software performs under the load k6 produces.

k6 is structured around four main pillars:

  1. Enabling users to script and configure their workloads
  2. Planning and executing tests
  3. Collecting measurements of software performance, such as response time
  4. Forwarding results to users

Let’s look at each of these pillars in greater detail:


With k6, users outline their workloads using JavaScript, which k6 runs using its goja interpreter. In addition, k6 supports various open source technologies, protocols, and tools, making it easier for users to interact with their software and infrastructure. Users can also customize k6 according to their needs, thanks to the tool’s extension and library system.

Planning and executing

Users can define specific execution scenarios they wish to replicate through configurable options. Then, k6 formulates an execution plan and orchestrates the workload to align with the user’s requirements as accurately as possible. For instance, in the example below, the options direct k6 to plan and execute two distinct scenarios, each with its own dedicated function, concurrently. As each scenario seeks to replicate different load characteristics, they each define properties instructing k6 to plan for specific execution behaviors:

export const options = {
 // By default, all scenarios are set to execute concurrently 
 scenarios: {

  // this scenario directs k6 to simulate 10 virtual users working together to execute the 'createUser' 200 times in total  
  user_creation: {
     exec: 'createUser',
     executor: 'shared-iterations',
     vus: 10,
     iterations: 200,

  // this scenario directs k6 to aim for executing the 'performTransaction' function 30 times per second, adding or removing Virtual Users (VUs) as necessary, starting with 50 VUs.
   transaction_execution: {
     exec: 'performTransaction',
     executor: 'constant-arrival-rate',
     rate: 30,
     preAllocatedVUs: 50,

export function createUser() {
  /* ... */

export function performTransaction() {
  /* ... */

Data collection

As k6 carries out the user-defined workload, it collects measurements, and classifies and aggregates them into metrics. Throughout the process, these measurements are sent to external outputs, which are then used to generate a report that offers performance insights to users. 

In the following example, we instruct k6 to execute a function sending HTTP GET requests to k6’s test API 3 times. With each HTTP request, k6 accumulates measurements encompassing a range of execution characteristics. For instance, each execution records the request’s duration, contributing to the http_req_duration metric.

import http from 'k6/http';

export const options = { iterations: 3 }

export default function () {

In response, the metric maintains a record of the progression of these collected measurements over time. It then aggregates them using various statistical functions, such as average, median, minimum, maximum, and percentile. The end-of-test summary report displays the resulting aggregated values.

For instance:

http_req_duration..............: avg=132.63ms min=116.55ms med=119.46ms 
max=168.23ms p(90)=167.01ms p(95)=167.62ms


As we have just seen, the end-of-test summary provides users with immediate, actionable insights, based on testing outcomes, directly in their terminal.

However, k6 can also broadcast metrics, forwarding their data points in real-time to external outputs. These outputs range from JSON or CSV files to databases and platforms like Prometheus, InfluxDB, and many more. This data can be processed and analyzed using tools like Grafana, providing users with a wide range of analysis options. 

The design of k6

To fulfill its mission, k6 is centered around two main components: an execution pipeline and a data pipeline.

Think about k6 as a simplified work scheduler, similar to those found in operating systems. Users write code to define the operations they want to perform and specify the constraints they wish to apply. k6 then creates an execution plan based on this code and its configuration, and orchestrates the process until completion.

As the code is executed and the scheduled plan progresses, k6 gathers measurements and funnels them into the data pipeline. This data is directed to real-time external outputs, enabling users to analyze it with their preferred tooling and according to their specific needs, as described above. In parallel, k6 classifies and aggregates the data to generate an end-of-test summary. 

Finally, as a load testing tool, k6 is engineered to execute code and carry out its plan swiftly and efficiently. To manage heavy workloads and high traffic volumes, it maximizes available hardware resources.

Next steps

Armed with a high-level overview of k6’s features and underlying design, you can start testing your applications under load — and much more — right now.

If you’re ready to put what you’ve learned into practice, sign up for Grafana Cloud k6 and follow our tutorial. The easiest way to get started is with our Grafana Cloud free tier, which offers 500 virtual user hours/month, 10k metrics, 50GB logs, 50GB traces, and more.

And if you have any questions or wish to learn more about specific aspects of k6, don’t hesitate to let us know.