k6 v2.1.0 is here π
This release includes:
- An opt-in feature-flag system β
--features, theK6_FEATURESenvironment variable, and ak6 featuresdiscovery command β shipping with experimental native histograms for trend metrics as its first flag. - A context-level
proxyoption for browser contexts. - Subcommand discovery in
k6 x, so binaries can report which extension commands they expose.
Breaking changes
There are no breaking changes in this release.
New features
k6 cloud test list command #6007
A new k6 cloud test command group has been added, with a k6 cloud test list subcommand that lists the load tests of a Grafana Cloud k6 project. It complements the k6 cloud project list command introduced in v2.0.0.
The project to list tests for is resolved in the following order:
- The
--project-idflag. - The
K6_CLOUD_PROJECT_IDenvironment variable (cloud configprojectID). - The default project of the configured stack, populated by
k6 cloud login.
Output defaults to a human-readable table. Pass --json to emit a JSON array instead, mirroring the format established by k6 cloud project list.
k6 cloud test list
k6 cloud test list --project-id 12345
k6 cloud test list --jsonFeature flags and experimental native histograms #6055, #6056
k6 now has an opt-in feature-flag mechanism for trialing new, not-yet-stable behavior without affecting existing runs. Flags can be enabled on k6 run and k6 cloud run through the --features flag (comma-separated or repeated), the K6_FEATURES environment variable, or the features key in config.json. Enabled flags are surfaced as metric tags and propagated into archives and cloud workers so a run behaves consistently wherever it executes.
Use k6 features (or k6 features --json) to discover the available flags and their lifecycle:
$ k6 features
FEATURE LIFECYCLE DESCRIPTION
native-histograms Experimental Use native histograms for trend metricsThe first flag shipped is native-histograms, an experimental flag that makes k6 use native histograms for trend metrics:
k6 run --features native-histograms script.js
# or
K6_FEATURES=native-histograms k6 run script.jsSubcommand discovery in k6 x #5972
Running k6 x now lists the available subcommands β both the ones baked into the binary and those advertised by the extension registry (official and community). Tab-completion surfaces the same set once the catalog has been cached locally by a prior k6 x run, so completion never blocks on the network.
$ k6 x
...
Available Commands:
agent Bootstrap an AI-assisted k6 testing workflow in any editor
docs CLI k6 docs for AI agents and users
explore Explore k6 extensions for Automatic Resolution
mcp An MCP server for k6 for AI agents
This makes a k6 binary self-describing β particularly useful for AI agents driving k6, which previously had no way to introspect which extension subcommands were available.
Browser context proxy option #5924
Browser contexts can now be configured with a context-level proxy option, letting you route a context's traffic through a proxy without launching a custom-built binary or relying on environment proxy variables (which only affected k6's DevTools WebSocket connection). The option is wired to Chromium through Target.createBrowserContext, and invalid proxy configuration now fails early when proxy.server is missing. Thanks, @nightt5879!
const context = await browser.newContext({
proxy: {
server: 'http://proxy.test:8080',
bypass: 'localhost,127.0.0.1',
},
});Browser locator.isInViewport() #6023
A new locator.isInViewport() method reports whether an element intersects the browser viewport. It accepts an optional ratio (0 to 1) that sets how much of the element must be visible, defaulting to 0 so any visible pixel counts, matching Playwright's toBeInViewport semantics. The call waits for the element to attach, honoring the timeout option, then measures the intersection once. Thanks, @Anuragp22!
const button = page.locator('button#submit');
if (await button.isInViewport()) {
await button.click();
}Basic auth for the OpenTelemetry HTTP exporter #5997
The OpenTelemetry output's HTTP exporter can now send HTTP Basic Auth credentials. Set them through the K6_OTEL_HTTP_EXPORTER_USERNAME and K6_OTEL_HTTP_EXPORTER_PASSWORD environment variables, or the username and password keys in the output config.
K6_OTEL_HTTP_EXPORTER_USERNAME=user \
K6_OTEL_HTTP_EXPORTER_PASSWORD=secret \
k6 run --out opentelemetry script.jssingle() selection helper in k6/html #6002
Selection.single(selector) returns at most one matching element, backed by goquery's Single matcher for a faster lookup than find() when you only need the first match. Thanks, @rohan-patnaik!
import { parseHTML } from 'k6/html';
const doc = parseHTML(content);
const title = doc.single('h1').text();UX improvements and enhancements
- #5971 Tags browser API failures with
module=browserso that browser errors surfaced in Grafana Cloud Logs can be filtered separately from other log sources.
Bug fixes
- #5794 Makes the
--vusflag work as a standalone execution shortcut instead of being silently ignored when a script defines scenarios. Runningk6 run script.js --vus Nnow creates ashared-iterationsscenario withNVUs andNiterations, overriding any script-defined scenarios with a warning β consistent with how--iterations,--duration, and--stagesalready behave. Thanks, @Reranko05! - #6013 Rejects invalid threshold percentiles. A percentile aggregation value outside the 0 to 100 range (or
NaN) now fails parsing with a clear message instead of being silently accepted. Thanks, @immanuwell! - #6011 Writes the on-disk k6 config file with owner-only permissions (
0o600, inside a0o700directory). The file can hold the Grafana Cloud API token (collectors.cloud.token), so tightening it keeps other local users on shared hosts (CI runners, multi-user boxes, sidecar containers) from reading the token. Existing configs are upgraded on the next write, for example the nextk6 cloud login.
Maintenance and internal improvements
- #6033 Moves Docker Hub image publishing to a Google Artifact Registry mirror.
- #5953 Installs
s3cmdviaaptinstead ofpipto fix thek6packagerimage build. - #6052 Fixes the browser end-to-end test workflow.
- #5984 Routes per-test logger output to the test instance instead of the global
logrus, improving test isolation. - #5985 Fixes the flaky
TestPageScreenshotFullpagebrowser test. - #5981 Lets Renovate track the Go minor version in the
setup-goworkflows. - #5968 Honors the caller-pinned ref in the shared lint action.
- #6041, #6054 Aligns the Go module directive and toolchain (1.25.0 / 1.25.11).
- #5967 Updates the release notes template after v2.0.0.
- #6015 Updates
golang.org/x/nettov0.55.0[security]. - #6026 Updates
golang.org/x/cryptotov0.52.0[security]. - #5962, #6028 Updates
google.golang.org/grpctov1.81.1. - #5960 Updates
grafana/shared-workflows/get-vault-secretstov1.3.2. - #5958 Updates
grafana/shared-workflows/azure-trusted-signingtov1.0.2. - #5957 Updates
github/codeql-actiontov4.35.4. - #5959 Updates
grafana/shared-workflows/dockerhub-logintov1.0.4. - #6009 Moves the browser
PageScreenshotOptionsparsing into the mapping layer. - #5964 Adds the k6 feature-flags specification under
openspec/. - #6067 Forces the legacy
x/net/http2implementation on thegotipCI test job. - #6065 Lets Renovate update the
Dockerfileon the v1.x branch. - #6031 Updates
go.opentelemetry.io/oteltov1.44.0. - #6086 Updates
golang.org/xdependencies (cryptotov0.53.0,nettov0.56.0,termtov0.44.0). - #6061 Updates
golang.org/x/synctov0.21.0. - #6030 Updates
github.com/tidwall/gjsontov1.19.0. - #6029 Updates
github.com/mccutchen/go-httpbin/v2tov2.23.0. - #6063 Updates
github.com/mattn/go-colorabletov0.1.15. - #6062 Updates the Golang Docker image to
1.26.4. - #6084 Updates the Alpine Docker image to
3.24.0. - #6027 Updates the Debian Docker image to
trixie-20260518.
External contributors
A huge thank you to the external contributors who helped during this release: @nightt5879, @Reranko05, @rohan-patnaik, @immanuwell, and @Anuragp22! π