---
title: "Version 2.2.0 release notes | Grafana k6 documentation"
description: "The release notes for Grafana k6 version 2.2.0"
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# 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](https://github.com/grafana/k6/pull/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 ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```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](https://github.com/grafana/k6/pull/6165)

The [browser module](/docs/k6/latest/javascript-api/k6-browser/) 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 ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```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](https://github.com/grafana/k6/pull/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 ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

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

### `WritableStream` in `k6/experimental/streams` [#6132](https://github.com/grafana/k6/pull/6132)

The experimental [streams module](/docs/k6/latest/javascript-api/k6-experimental/streams/) now implements `WritableStream` and `WritableStreamDefaultWriter` following the WHATWG Streams specification, complementing the existing `ReadableStream`.

js ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```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](https://github.com/grafana/k6/pull/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 ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```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](https://github.com/grafana/k6/pull/5854)

The time budget for the `handleSummary()` callback — previously hardcoded to 120 seconds — is now [configurable](/docs/k6/latest/using-k6/k6-options/reference/#handle-summary-timeout) 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 ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

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

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

Two new [experimental feature flags](/docs/k6/latest/using-k6/feature-flags/) join the feature-flag system introduced in v2.1.0:

- [#5714](https://github.com/grafana/k6/pull/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](https://github.com/grafana/k6/pull/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 ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```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](https://github.com/grafana/k6/blob/master/release%20notes/v2.2.0.md).
