Open-source project
grafana/k6 avatar
grafana/k6

Grafana k6: Load Tests Written as JavaScript Scripts, Executed by a Go Binary

A modern load testing tool, using Go and JavaScript

32,283 stars1,719 forksGoAGPL-3.0

At a glance

What is it?
k6 turns load testing into version-controlled JavaScript that runs on an embedded JS engine inside a Go runtime. It is a strong fit for CI pipelines and protocol-level API testing, and a poor fit for teams that need real browser rendering at thousands of virtual users.
Who is it for?
Adopt k6 if your team already writes JavaScript, wants thresholds such as http_req_duration: ["p(99) < 3000"] enforced as pass or fail inside CI, and tests HTTP, WebSockets or gRPC endpoints rather than rendered pages.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • grafana/k632,283 ★ · +823
Star history
Repository2026-09-132026-11-13
grafana/k631.5k32.3k

823 Stars in the last 61 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The Problem k6 Targets: Load Tests That Live Outside Version Control

Load testing has traditionally been split between GUI-driven tools where the test definition lives in a proprietary file, and hand-rolled scripts that generate traffic but report nothing structured. k6's stated design goal in the README is to provide "the best developer experience", and the mechanism for that is treating the test itself as source code. The README lists "Tests as code" as a core feature, with the explicit benefits being reuse, modularization, version control, and CI integration.

The audience is correspondingly narrow. This is for developers and testers who are comfortable writing JavaScript and who want performance assertions to fail a build the same way a unit test does. The README frames it as "Like unit testing, for performance", which is a fair summary of the intent: the test is a file, the pass or fail condition is declared in that file, and the runner is a command-line binary. Teams that want a point-and-click recorder are pointed at a separate project, k6 Studio, described in the README as a desktop application for generating k6 scripts without touching code. That separation is deliberate. The core tool assumes you can read and edit the script.

How the Go Binary and the Embedded JavaScript Engine Fit Together

The architecture is a Go program that embeds a JavaScript engine. The README states this directly: "An embedded JavaScript engine. The performance of Go, the scripting familiarity of JavaScript." The practical consequence is that a script is not sent to a separate interpreter process. It is evaluated inside the same runtime that schedules virtual users and collects metrics. The README separately claims that even lower-end machines can simulate lots of traffic.

Data flow follows a fixed shape. A script exports an options object and a default function. The options object declares thresholds and stages. The default function is the body of a virtual user's iteration. In the README example, the default function issues one HTTP GET through the k6/http module, and runs a check on the response status. The stages array ramps the virtual user count from zero to fifteen over thirty seconds, holds for one minute, and ramps back to zero over twenty seconds.

Metrics are produced by the runtime rather than by the script. The README example asserts on http_req_duration, a metric the tool generates automatically for HTTP requests, using the expression p(99) < 3000. That means the script author never writes timing code; they write assertions against counters and distributions the engine already maintains. Results can be viewed as summary statistics or exported in granular form to an external service, per the README's description of flexible metrics storage.

Running a Test: The CLI, the options Object, and the Threshold Expression

The concrete entry points are visible in the README example. A script imports from k6/http and from the k6 module itself:

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

Configuration is exported, not passed as flags, which is what makes the test portable between a laptop and a CI job:

export const options = { thresholds: { http_req_duration: ["p(99) < 3000"], }, stages: [ { duration: "30s", target: 15 }, { duration: "1m", target: 15 }, { duration: "20s", target: 0 }, ], };

The threshold value is a string expression evaluated against an aggregated metric. p(99) < 3000 means the 99th percentile of request duration must stay under 3000 milliseconds. If it does not, the run is a failure, which is the hook that makes the tool usable as a CI gate rather than a reporting dashboard.

Options beyond thresholds and stages are documented under k6 options, covering load, duration, and TLS certificates. Scenarios are the layer above stages, and the README describes them as the way to choose a workload model: open models, closed models, constant request rate, and fixed iteration counts. The README does not enumerate the exact config keys for each scenario type, so check the options and scenarios documentation pages before assuming a particular key name. The README also notes scripts can run on the CLI, in CI, or across a Kubernetes cluster, though the Kubernetes path is not shown in the README.

Where k6 Stops Being the Right Tool

The most consequential limitation is the JavaScript engine. It is embedded and purpose-built, not a browser and not Node.js. The README lists Browser as one of the supported protocols, but a browser protocol driven from a load generator is not the same thing as a rendering engine under real user conditions. If your application's failure mode only appears after client-side rendering, hydration, or third-party script execution, a script that issues HTTP calls will not reproduce it. The README's own example, a single GET to quickpizza.grafana.com with a status check, illustrates the level of abstraction: request and response, not pixels.

A second boundary is the extension ecosystem. The README presents extensions as a feature and links to a catalogue, but anything outside the core protocol set depends on code that is versioned separately from the k6 binary. That is a maintenance surface you inherit. A protocol supported only by a third-party extension can lag behind k6 releases, and the recent release list shows the project ships frequently: v1.8.1, v2.3.0 and v1.8.2 all appear within roughly two months.

A third point is licensing, discussed separately below, which rules k6 out for some commercial embedding scenarios regardless of technical fit.

The Honest Alternative: JMeter and the Difference in Approach

Apache JMeter is the natural comparison, and the difference is structural rather than cosmetic. JMeter is a Java application whose test plans are typically built in a graphical interface and stored as XML. Its logic is assembled from configurable elements: thread groups, samplers, listeners, and controllers. You extend it by writing Java classes or by installing plugins.

k6 inverts both halves of that. The test is a JavaScript module, so the control flow is ordinary code with imports, functions, and loops, and the whole file diffs cleanly in a pull request. The runner is a single Go binary rather than a JVM application with a heap to tune, which matters when the load generator itself is competing for CPU with the system under test. The cost of the inversion is that you cannot click your way to a test plan, and the README acknowledges this by pointing non-coders at k6 Studio.

Choose JMeter when your organisation already has GUI-authored plans, Java plugin expertise, or a protocol that only JMeter covers. Choose k6 when the test should be reviewed like application code and executed by a CI runner that installs a binary and nothing else.

Licence and Upgrade Costs Under AGPL-3.0

k6 is licensed AGPL-3.0. The practical question is not whether you may run it, which you may, but what happens when you distribute it or a modified version, or expose a modified version over a network. The AGPL's network clause is the part that differs from the GPL, and it is the part that catches teams who embed a tool inside a hosted product. If you only run the unmodified binary internally to generate load against your own systems, the obligation is minimal. If you fork it, link it into a service, or offer it to third parties, the analysis changes and belongs with your legal team, not with a review article. Nothing here is legal advice.

Upgrade cost is a function of release cadence. The release list shows v1.8.1 on 2026-08-12, v2.3.0 on 2026-09-21, and v1.8.2 on 2026-10-12, which suggests parallel maintenance lines rather than a single linear track. That means a pinned version needs a deliberate decision about which line you are on. The README's contribution guidance asks contributors to discuss large changes with maintainers before coding, which is a signal that the project does not accept arbitrary patches silently. For consumers, the corresponding discipline is to read release notes before bumping, particularly if you depend on extensions that track the core binary.

Who Should Adopt k6, and What to Confirm First

The fit is clearest for a backend or platform team that already writes JavaScript, tests HTTP or gRPC endpoints, and wants a performance assertion to run in the same pipeline as the unit tests. The thresholds mechanism is the reason: p(99) < 3000 is a machine-checkable statement, and a threshold breach fails the run.

The fit is poor for a front-end team whose bugs only surface in a rendered page, and for anyone who needs a graphical test builder as the primary authoring surface, for whom k6 Studio is the relevant project rather than this repository.

Before adopting, confirm three things. First, whether AGPL-3.0 is acceptable given how you intend to deploy the binary. Second, whether every protocol you need is in the core modules or in an extension you are prepared to track across k6 releases. Third, whether the scenario model you need, open, closed, constant rate, or fixed iterations, maps to a documented config key, since the README names the models but does not list their keys. The README example is the smallest useful starting point: one GET, one check, one threshold, three stages.

Editorial conclusion

Adopt k6 if your team already writes JavaScript, wants thresholds such as http_req_duration: ["p(99) < 3000"] enforced as pass or fail inside CI, and tests HTTP, WebSockets or gRPC endpoints rather than rendered pages. Do not adopt it as a replacement for a browser-driven suite when the behaviour under test only appears after client-side rendering, and do not treat the free binary as interchangeable with the hosted Grafana Cloud execution service if you need distributed generation. Verify two things before committing: that the AGPL-3.0 obligations are acceptable to your legal team, and that your target protocol is covered by the core modules or by an extension you are willing to maintain.

Frequently asked questions

Is Grafana k6 free?

The tool is distributed under the AGPL-3.0 licence, and the front page links a download, the documentation, a community forum and a public roadmap. It also points at a hosted option from Grafana Cloud for running tests, correlating metrics and analysis, and at a separate desktop project for generating scripts without writing code.

what is grafana k6

It is a modern load testing tool written in Go with an embedded JavaScript engine, so tests are scripts you can reuse, modularise and keep in version control. Its listed features include configurable load generation, protocol support across HTTP, WebSockets, gRPC and a browser, an extension ecosystem, and metrics exported to a service you choose.

How to execute k6 script?

The README says scripts like the one it shows can run on the command line, in continuous integration, or across a Kubernetes cluster. A script exports an options object, where the example sets a duration threshold and a three stage ramp, and exports a default function that issues the requests.

what is grafana k6 studio

It is a separate desktop application, in its own repository, that the front page offers to anyone who would rather not write code. Its stated purpose is to help you generate k6 scripts without touching code, and it is not part of the k6 binary itself.

Is k6 better than JMeter?

The README does not compare k6 with JMeter. What it states about k6 itself is the Go core with an embedded JavaScript engine, tests as code with version control, protocol support, and an extension ecosystem for anything the built-in modules do not cover.

what does grafana k6 stand for

The README does not expand the name k6 into anything. It describes itself as a modern load testing tool using Go and JavaScript, and its headline line is that it is like unit testing but for performance.

Official sources

  1. grafana/k6 on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/grafana-k6.svg)](https://hysenlabs.com/projects/grafana-k6)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/grafana-k6.svg)](https://hysenlabs.com/projects/grafana-k6)

Was this useful?