k6 group() preserves metric context across asynchronous calls
Introduced 2026-09-21 · score 0.96
HOW TO USE IT
When an asynchronous test flow needs requests and checks to remain in one group across `await`, run it with the experimental `async-metric-context` feature and use an async `group()` callback. `group_duration` then measures until the callback’s returned promise settles.
k6 run --features async-metric-context <script.js>import { check, group } from 'k6';
import http from 'k6/http';
export default async function () {
await group('browse', async () => {
const response = await http.asyncRequest('GET', 'https://test.k6.io/');
check(response, { 'page loaded': (r) => r.status === 200 });
await http.asyncRequest('GET', 'https://test.k6.io/contacts.php');
});
}WHY THIS HELPS
When debugging an asynchronous test flow, keep its requests and checks grouped across awaited calls.
BEFORE THIS CHANGE
`group()` rejected async functions by default, and promise callbacks could lose the group tag.
REQUIREMENTS AND LIMITATIONS
- Version: v2.3.0
- Availability: experimental; enable the `async-metric-context` feature
- --features async-metric-context: Enables the experimental feature that permits async `group()` callbacks and propagates metric tags and metadata to asynchronous work. Required to use async callbacks in `group()`; the docs also allow enabling it with `K6_FEATURES=async-metric-context`.
- group(name, fn): name (required): String name of the group.
- group(name, fn): fn (required): Function containing the group body; with the feature enabled it may be async or return a Promise-like value.
- http.asyncRequest(method, url): method (required): Uppercase HTTP method, such as `GET`.
- http.asyncRequest(method, url): url (required): HTTP request URL.
- Prerequisite: Enable the experimental, opt-in `async-metric-context` feature using `--features async-metric-context` or `K6_FEATURES=async-metric-context`.
- Changes inside a group or callback stay local to that work and its asynchronous descendants instead of leaking into unrelated work.
- Custom tags and metadata are preserved across promises, timer callbacks, `k6/websockets` listeners, and gRPC stream listeners.
FIRST-PARTY EVIDENCE
- https://github.com/grafana/k6/releases/tag/v2.3.0
- https://grafana.com/docs/k6/latest/javascript-api/k6/group/
- https://grafana.com/docs/k6/latest/javascript-api/k6-http/
Check the installed version and the source before using it. Entry JSON