This is documentation for the next version of Grafana k6 documentation. For the latest stable release, go to the latest version.

Open source

Version 2.2.0 release notes

k6 v2.2.0 is here 🎉! This release includes:

  • k6 cloud run --local-execution now streams k6’s logs to Grafana Cloud, so the test run’s log view works for local execution too.
  • chromium.connectOverCDP(), which connects browser tests to an already-running Chromium instance.
  • TextEncoder and TextDecoder available as globals, and WritableStream support in k6/experimental/streams.
  • A k6 cloud load-zone list command.
  • Two new experimental feature flags: merge-run-tags and freeze-env.

Breaking changes

There are no breaking changes in this release.

New features

k6 cloud run --local-execution streams logs to Grafana Cloud #6171

When a cloud test runs locally with k6 cloud run --local-execution, k6’s logs now stream to the Grafana Cloud test run, so the run’s log view is populated the same way it is for cloud execution. Use the new --no-cloud-logs flag to opt out of streaming logs when working with --local-execution:

shell
k6 cloud run --local-execution script.js
k6 cloud run --local-execution --no-cloud-logs script.js

Connect to a running browser with chromium.connectOverCDP() #6165

The browser module can now attach to an existing Chromium-based browser over the Chrome DevTools Protocol, mirroring Playwright’s browserType.connectOverCDP(). Pass the browser’s WebSocket endpoint and k6 manages the returned browser’s connection — it’s auto-closed at the end of the iteration, though you can call close() earlier to release the connection on demand.

js
import { chromium } from 'k6/browser';

export default async function () {
  const browser = await chromium.connectOverCDP('ws://localhost:9222/devtools/browser/<id>');
  const page = await browser.newPage();

  try {
    await page.goto('https://quickpizza.grafana.com/');
  } finally {
    await page.close();
    await browser.close();
  }
}

Unlike the K6_BROWSER_WS_URL environment variable, the endpoint is a runtime value — you can, for example, request a fresh session URL from a browser provider’s API in setup() and connect to it from the iterations.

TextEncoder and TextDecoder globals #6182

TextEncoder and TextDecoder are now available as standard globals in both the init and VU contexts, no import required — matching how they are exposed in browsers and other JavaScript runtimes.

js
const encoded = new TextEncoder().encode('Hello, world!');
const decoded = new TextDecoder().decode(encoded);

WritableStream in k6/experimental/streams #6132

The experimental streams module now implements WritableStream and WritableStreamDefaultWriter following the WHATWG Streams specification, complementing the existing ReadableStream.

js
import { WritableStream } from 'k6/experimental/streams';

export default async function () {
  const stream = new WritableStream({
    write(chunk) {
      console.log(`wrote ${chunk}`);
    },
  });

  const writer = stream.getWriter();
  await writer.write('hello');
  await writer.close();
}

k6 cloud load-zone list command #6142

A new k6 cloud load-zone list subcommand lists the load zones — public and private — available in the configured Grafana Cloud k6 stack, mirroring the existing k6 cloud project list command. Output defaults to a human-readable table; pass --json to emit a JSON array instead.

console
$ k6 cloud load-zone list
Load zones for https://example.grafana.net:

ID                     NAME                     TYPE      AVAILABLE
amazon:us:ashburn      Ashburn, US (Amazon)     public    yes
amazon:sa:cape town    Cape Town, SA (Amazon)   public    yes

Configurable handleSummary() timeout #5854

The time budget for the handleSummary() callback — previously hardcoded to 120 seconds — is now configurable through the handleSummaryTimeout option or the K6_HANDLE_SUMMARY_TIMEOUT environment variable, so long-running tests with heavy summaries no longer fail with handleSummary() execution timed out. Thanks, @LBaronceli!

js
export const options = {
  handleSummaryTimeout: '5m',
};

New experimental feature flags: merge-run-tags and freeze-env

Two new experimental feature flags join the feature-flag system introduced in v2.1.0:

  • #5714 merge-run-tags merges run tags per key across config layers, so options.tags in a script is no longer silently discarded when --tag or K6_TAGS is also used. Thanks, @yordis!
  • #6032 freeze-env freezes the __ENV object, so modifications from script code throw a TypeError (in strict mode) instead of silently persisting across iterations and scenarios. Thanks, @lohitkolluri!
shell
k6 run --features merge-run-tags,freeze-env script.js

For a full list of changes, including UX improvements and bug fixes, refer to the full release notes.