github grafana/k6 v2.0.0-rc1

8 hours ago

k6 v2.0.0-rc1 is here 🎉!

This release marks the first release candidate for k6 v2.0.0 — a major version that completes a long-running cleanup of deprecated APIs, old commands, and obsolete configuration options. Like the v1.0.0-rc1 before it, the purpose of this release is to give the community a chance to test the upgrade path, identify any issues, and migrate scripts or workflows affected by breaking changes. If you encounter any problems, please report them.

Here's a glimpse of what's changed in this release:

  • The Go module path has changed to go.k6.io/k6/v2 — all extensions must update their import paths to be compatible with v2.
  • Removal of all long-deprecated CLI commands and flags: k6 login, k6 pause, k6 resume, k6 scale, k6 status, --no-summary, --upload-only, and more.
  • The externally-controlled executor has been removed — scripts using executor: externally-controlled will no longer run.
  • Cloud run non-threshold aborts (aborted by user, system, timeout, etc.) now return exit code 97 instead of 0.
  • options.ext.loadimpact is no longer supported — use options.cloud.
  • k6/experimental/redis module has been removed.
  • The k6 cloud command now shows help by default instead of attempting to run.
  • A stack is now required for all k6 cloud commands — the previous fallback to the first available stack has been removed.
  • The web-vitals library has been updated to v5.1.0, removing the deprecated FID metric.

Breaking changes

These are changes that require you to update your scripts, CI/CD pipelines, or configuration files before upgrading.

Go module path changed to go.k6.io/k6/v2 #5777

Following the Go module versioning conventions, the k6 module path has changed from go.k6.io/k6 to go.k6.io/k6/v2.

Any extension or external package that imports go.k6.io/k6 must update all import paths to go.k6.io/k6/v2. For the vast majority of extensions this is the only change needed — a mechanical find-and-replace across the codebase:

go.k6.io/k6/ → go.k6.io/k6/v2/

For example:

// Before
import "go.k6.io/k6/js/modules"

// After
import "go.k6.io/k6/v2/js/modules"

As a result, no existing extensions will be compatible with v2.0.0-rc1. As we move toward the final v2.0.0 release, we expect most extensions to either already support the new path or to do so shortly after.

Removed CLI commands #5653

The following commands for controlling a running test have been removed. They have not been functional for most use cases since the REST API they relied on was limited to specific execution modes:

  • k6 pause
  • k6 resume
  • k6 scale
  • k6 status

Migration: There is no replacement. These commands relied on the externally-controlled executor, which has also been removed in v2.0.0 (see below).

Removed externally-controlled executor #5846

The externally-controlled executor has been removed. It was legacy code from an older k6 Cloud architecture that allowed external systems to scale VUs and pause/resume a running test via the k6 REST API — the capability that k6 pause, k6 resume, k6 scale, and k6 status relied on.

Migration: There is no replacement. Any test script with executor: externally-controlled will fail to start. Migrate to a different executor based on the desired load profile (e.g., ramping-vus, constant-vus, constant-arrival-rate).

Removed k6 login command #5134

The top-level k6 login command and its subcommands (k6 login cloud, k6 login influxdb) have been removed.

Migration:

  • Replace k6 login cloudk6 cloud login
  • InfluxDB authentication is no longer configurable via a login command. Use environment variables such as K6_INFLUXDB_* to configure the InfluxDB output directly.

k6 cloud script.js no longer runs a test #5624

Running k6 cloud without an explicit subcommand (i.e., the old positional-argument form k6 cloud script.js) now shows the help output instead of attempting to run the test. The run subcommand was already the recommended path since k6 cloud run was introduced.

Migration: Replace k6 cloud script.js with k6 cloud run script.js.

Removed --upload-only flag #5844

The --upload-only flag on the k6 cloud command has been removed.

Migration: Use k6 cloud upload script.js to upload a test without running it.

Removed --no-summary flag #5729

The --no-summary flag has been removed.

Migration: Replace --no-summary with --summary-mode=disabled.

Removed --summary-mode=legacy #5730

The legacy value for --summary-mode has been removed.

Migration: There is no direct equivalent — the new summary format is different from the legacy one. Review the available summary modes and choose the one that best fits your needs: compact (the default) or full for more detailed output.

Removed options.ext.loadimpact support #5774

The options.ext.loadimpact configuration block in test scripts is no longer supported.

Migration: Move all cloud-related configuration from options.ext.loadimpact to options.cloud:

// Before
export const options = {
  ext: {
    loadimpact: {
      projectID: 12345,
      name: "My Test",
    },
  },
};

// After
export const options = {
  cloud: {
    projectID: 12345,
    name: "My Test",
  },
};

Removed k6/experimental/redis module #5485

The k6/experimental/redis module has been removed from the k6 core binary. It was shipped as an experiment and has not been promoted to stable.

Migration: Change your import from k6/experimental/redis to k6/x/redis. With auto-extension-resolution, k6 will automatically provision the xk6-redis extension when it sees the k6/x/redis import.

Removed ExporterType option from OpenTelemetry output #5754

The deprecated exporterType configuration option for the OpenTelemetry output has been removed.

Migration: Replace K6_OTEL_EXPORTER_TYPE with K6_OTEL_EXPORTER_PROTOCOL. The accepted values are grpc and http/protobuf.

Removed SingleCounterForRate option from OpenTelemetry output #5830

The temporary SingleCounterForRate escape-hatch option for the OpenTelemetry output has been removed. It was introduced as a one-release migration aid in #5164 to let users revert to the old pair-of-counters format (<metric>.occurred + <metric>.total) while upgrading. Rate metrics are now always exported as a single counter with a condition attribute (nonzero/zero).

Migration: Remove any K6_OTEL_SINGLE_COUNTER_FOR_RATE=true configuration. If you were using the old pair-of-counters format, update your dashboards and queries to use the single counter with condition attribute instead.

Removed K6_BINARY_PROVISIONING environment variable #5734

The K6_BINARY_PROVISIONING environment variable, deprecated in v1.2.0, has been removed.

Migration: Remove K6_BINARY_PROVISIONING from your environment. Auto-extension-resolution is enabled by default; K6_AUTO_EXTENSION_RESOLUTION only needs to be set explicitly if you want to disable it.

Removed K6_ENABLE_COMMUNITY_EXTENSIONS environment variable #5733

The K6_ENABLE_COMMUNITY_EXTENSIONS environment variable has been removed. The community and cloud extension catalogs were merged server-side, making this flag a no-op since the catalogs were unified.

Migration: Remove K6_ENABLE_COMMUNITY_EXTENSIONS from your environment. Community extensions are now resolved through the default build service URL automatically.

Stack is now required for all k6 cloud commands #5833

Providing a stack is now mandatory for all k6 cloud commands (k6 cloud run, k6 cloud upload, k6 cloud run --local-execution). Previously, omitting a stack would fall back to the first available stack with a deprecation warning — that fallback has been removed. Likewise, k6 cloud login now requires both a token and a stack; passing one without the other fails with an explicit error.

Migration: Run k6 cloud login which will ask you for the stack and setup correctly for the new version of k6. Alternatively, the K6_CLOUD_STACK_ID environment variable, or the stackID script option are available to be set before running any k6 cloud command .

Removed legacy configuration file path migration #5609

k6 no longer automatically migrates configuration files from the old {USER_CONFIG_DIR}/loadimpact/config.json path introduced before k6 v1.0.0.

Migration: If you still have a config file at the old path, move it to {USER_CONFIG_DIR}/k6/config.json. You can also re-run k6 cloud login to regenerate the file at the correct location.

Cloud run non-threshold aborts now exit with code 97 #5769

Previously, most cloud abort scenarios returned an exit code of 0, making it impossible for CI pipelines to distinguish a failed run from a successful one. These scenarios now return exit code 97.

Scenario Before After
Finished 0 0
Aborted by threshold 99 99
Aborted by system, limit, script error, user, or timeout 0 97

Migration: Review any CI pipeline logic that treats exit code 0 as success for cloud runs. Cloud runs that abort for reasons other than threshold violations will now return exit code 97.

Browser: FID metric removed, web vitals updated to v5.1.0 #5661

The browser_web_vital_fid metric has been removed. FID (First Input Delay) was deprecated as a Core Web Vital and replaced by INP (Interaction to Next Paint). The embedded web-vitals library has been updated from v3 to v5.1.0, which reflects this change.

Migration: Update any dashboards, alerts, or threshold rules that reference browser_web_vital_fid to use browser_web_vital_inp instead.

New features

Cloud secret source #5738

A new built-in secret source, cloud, allows k6 scripts to retrieve secrets stored in Grafana Cloud directly during local execution. Pass --secret-source=cloud when running k6 cloud run --local-execution to make cloud-managed secrets available to your script via secrets.get(). Thanks, @vortegatorres!

k6 cloud run --local-execution --secret-source=cloud script.js

Extension tab-completion provisioning #5761

When using shell tab-completion, pressing TAB after a fully-typed extension name (e.g. k6 x docs <TAB>) will now automatically provision a custom binary with that extension and delegate the completion request to it. This means extension-specific flags and subcommands are available via tab-completion without any manual setup.

Pre-manifest extension dependencies captured in archive metadata #5819

When creating a k6 archive (k6 archive), extension dependency information is now captured in metadata.json under a "dependencies" field, using the constraints declared by the script before any external manifest overrides are applied. This ensures that k6/x/ imports are preserved correctly during auto-extension-resolution re-execution.

UX improvements and enhancements

  • #5815 Warns when http.get() or http.head() receive extra arguments that are silently ignored, helping catch common scripting mistakes. Thanks, @moko-poi!
  • #5657 Adds automatic retries to newAction-based Locator APIs in the browser module, improving reliability of browser tests. Thanks, @janHildebrandt98!
  • #5779 Adds a k6 x docs hint to the main k6 help output for built-in documentation discovery. Thanks, @Reranko05!
  • #5788 Adds a k6 x explore hint to the main k6 help output for extension discovery.

Bug fixes

  • #5855 Fixes auto-extension-resolution incorrectly triggering binary provisioning when a script manifest specifies a dependency as a Go module pseudo-version (v0.0.0+sha or v0.0.0-timestamp-sha), even when the running binary already satisfied the constraint.
  • #5769 Fixes several k6 cloud run TUI issues: ghost duplicate progress bars appearing after the run finishes, a timer that stalled and then jumped to 100%, and a stale timer racing with the status line.
  • #5814 Fixes k6 cloud run --local-execution ignoring K6_CLOUD_PUSH_REF_ID and unconditionally creating a new test run instead of reusing the provided run ID. Thanks, @Reranko05!
  • #5716 Fixes WebSocket bufferedAmount not being incremented when sending TypedArrays, causing it to go negative. Thanks, @prakharbirla-ng!
  • #5630 Fixes duplicate redirect request metric emissions in the browser module, where each redirect was incorrectly emitting metrics for all prior redirects in the chain.
  • #5786 Fixes swapped Min and Max values for Gauge metrics in Cloud output v2, which caused incorrect peak and floor values in cloud test result queries. Thanks, @esquonk!
  • #5785 Fixes a race condition in the browser module's handleExitEvent where Done() was signalled before the subscription was removed, causing tests to hang until the timeout.
  • #5574 Fixes position parser for base pointer options. Thanks, @chrismooreproductions!

Maintenance and internal improvements

  • #5847 Moves TaskQueue from the external github.com/mstoykov/k6-taskqueue-lib into internal/js/taskqueue, eliminating an awkward reverse dependency where the library's own tests depended on k6.
  • #5775 Moves xk6-dashboard source code into internal/dashboard, making the web dashboard a built-in part of the k6 binary without requiring a separate extension. The dashboard is available via k6 run --out=web-dashboard.
  • #5703, #5818 Uses Go's synctest package within lib/executor, eventloop, and timer tests for virtualized time, improving test determinism.
  • #5778 Bumps Ubuntu CI runners to 24.04 and always installs Chromium for browser tests.
  • #5826, #5827 Updates go.opentelemetry.io/otel/exporters/otlp/otlptracehttp and otlpmetrichttp to v1.43.0 [security], adding a 4 MiB response body cap to mitigate memory exhaustion from misconfigured or malicious servers.
  • #5669 Updates go.opentelemetry.io/otel packages.
  • #5740, #5796 Updates github.com/grafana/sobek digest.
  • #5783, #5838, #5862 Updates github.com/grafana/k6-cloud-openapi-client-go.
  • #5407, #5801 Updates github.com/mailru/easyjson to v0.9.2.
  • #5616, #5805 Updates github.com/evanw/esbuild to v0.28.0.
  • #5667 Updates golangci-lint.
  • #5799 Updates buf.build/gen/go/prometheus protobuf.
  • #5800 Updates github.com/andybalholm/brotli to v1.2.1.
  • #5804 Updates examples/ dependencies.
  • #5806 Updates github.com/fatih/color to v1.19.0.
  • #5807 Updates github.com/puerkitobio/goquery to v1.12.0.
  • #5840 Updates github.com/mattn/go-isatty to v0.0.21.
  • #5857 Updates Go to v1.25.9.
  • #5863, #5880 Updates github.com/grafana/k6provider to v0.4.0.
  • #5670 Updates GitHub artifact actions (major).
  • #5693 Updates crazy-max/ghaction-chocolatey to v4.
  • #5706 Updates actions/setup-go to 4a36011.
  • #5707 Updates anchore/sbom-action to v0.24.0.
  • #5718, #5861 Updates github/codeql-action to v4.35.2.
  • #5720, #5802 Updates docker/login-action to v4.1.0.
  • #5771, #5798 Updates grafana/shared-workflows actions.
  • #5836 Updates actions/upload-artifact.
  • #5809, #5839 Updates the Docker base image tags (Debian to v13, Go to v1.26.2).
  • #5872 Fixes v6 cloud client losing the request body when retrying after a Connection: close response.
  • #5871 Returns an accurate error from the v6 cloud client when a test name lookup returns no results.
  • #5751 Updates github.com/klauspost/compress to v1.18.5.
  • #5841 Updates golang.org/x packages.
  • #5860 Updates Alpine Docker image to v3.23.4.

External contributors

A huge thank you to the external contributors who helped during this release: @moko-poi, @janHildebrandt98, @Reranko05, @prakharbirla-ng, and @chrismooreproductions! 🙏

Don't miss a new k6 release

NewReleases is sending notifications on new releases.