K6 v0.32.0 is out! 馃帀

:tada: v0.32.0 Release Announcement

Sorry for the delay this time. The new version has been available for 16 days at the time of writing, but for completeness; here goes:

Originally posted at Release v0.32.0 路 grafana/k6 路 GitHub

k6 v0.32.0 is here! :tada: It鈥檚 a smaller release, featuring mostly chores that we never got to or that needed to be done in this release cycle, but also includes a significant performance improvement for arrival-rate executors and some breaking changes.

Move out of Bintray

Bintray has stopped servicing users on 1st of May, which meant that we needed to move the deb and rpm repositories out of there before then. Please follow the new installation instructions and the 鈥淣ote about Bintray鈥 to find out how to remove the old repository if you have used them.

Notable changes

Move all outputs to new Output interface introduced in v0.31.0 and other related changes

We started on this in the previous v0.31.0 release and now all internal outputs implement the new Output interface we provided for xk6 output extensions. Additionally one of the old built-in outputs is being deprecated and one renamed:

  1. The kafka output has been somewhat neglected since it was added 3 years ago. Additionally it brings a lot of complexity and isn鈥檛 well understood by anyone on the team. Given that output extensions are possible since the last version, the Kafka output has been moved to one. The built-in output will continue to work for a few more k6 versions, emitting a deprecation warning when used, so that everyone has time to transition to the extension. All future improvements will happen only in the extension, the built-in output is frozen until it鈥檚 dropped.
  2. We are also deprecating/renaming the datadog output. It should鈥檝e probably always been just a configuration of the statsd output and now in k6 v0.32.0, it is going to be just that. We鈥檝e added a new K6_STATSD_ENABLE_TAGS option to the statsd output, which, when enabled (it鈥檚 false by default), will send metric tags the same way the datadog output did before. That is, instead of using the datadog output, you should use the statsd one with K6_STATSD_ENABLE_TAGS=true. Additionally, the new K6_STATSD_TAG_BLOCKLIST option can be used to not send tags that the user doesn鈥檛 want to, similar to the old K6_DATADOG_TAG_BLACKLIST option.
    This makes it cleaner to also emit metrics to other services that accept the same data and tag formats, such as New Relic, Amazon Cloudwatch, and statsd >v0.9.0. The old datadog output will still work for a few k6 versions, emitting a warning to switch to statsd when used.

Apart from a message about them being deprecated, nothing should be changed from the actual refactoring yet, but we advise users to use the proposed alternatives starting with this release.

json output emits thresholds defined on the metrics (#1886)

Previous to this change thresholds were not included in the json output. Now the Metric JSON object will get its thresholds field properly populated.

Thanks to @codebien for this contribution!

cloud output has an option to abort the test if aborted from the cloud (#1965)

In v0.26.0 we made the cloud output stop emitting metrics if it gets a particular error from the backend, as that meant that the test was aborted in the cloud. Now we added K6_CLOUD_ABORT_ON_ERROR to be able to say that it should not only stop emitting metrics, but also stop the execution of the local k6 test run. The default configuration is false, so it is backwards compatible. This also works when the test is aborted by the user or if cloud execution limits are reached, which would also lead to the test being aborted.

Full stack traces for init context and setup/teardown exceptions (#1971)

For a long time, if there was an exception in either the init context or in the setup() or teardown() invocations, the stack trace would be just the last line, making it really hard to debug issues there. Now there is a full stack trace and, as such errors will result in aborted k6 execution, k6 run will also exit with exit code 107, signalling a script error.

Considerable performance improvements for arrival rate executors (#1955)

Due to a wrong re-usage for a particular internal data structure, the arrival rate executors were having a much worse performance than expected. With this release they should be a lot more performant, especially with large numbers of VUs.

Updating the majority of our dependencies and dropping some

The list is too long and we have been postponing updating for quite some time now, but we have finally updated all our dependencies that we don鈥檛 want to drop. This could lead to some stability problems, which is why it was done early on in the cycle. While the team has not found any regressions, given all the updates we could have missed something so please open a issue if you find anything.

Some notable updates:

  • goja, the JS engine we use got support for let/const which allowed us to disable a Babel plugin. Previous to this if you had a particularly long script sometimes Babel took upwards of 30 minutes to transpile. Now even our worst contender that previously took 51 minutes is transpiled in less than a minute :tada:. Also globalThis is now available.
  • updating the gRPC libraries fixed bug (#1928) and probably others. (#1937)

ArrayBuffer is now supported in all JS APIs dealing with binary data, including in WebSocket messages (#1841)

Besides the minor breaking changes (see the 鈥淏reaking changes鈥 section below), it鈥檚 now possible to send binary WS messages with the socket.sendBinary() function and to receive binary messages with the binaryMessage event handler:

const binFile = open('./file.pdf', 'b');

export default function () {
  ws.connect('http://wshost/', function(socket) {
    socket.on('open', function() {

    socket.on('binaryMessage', function(msg) {
      // msg is an ArrayBuffer, so we can wrap it in a typed array directly.
      new Uint8Array(msg);

Official arm64 releases for macOS and Linux (#2000)

We will now publish binary arm64 releases for macOS and Linux for new k6 releases. Support for these new architectures should be stable, given Go鈥檚 cross-platform compatibility, but please report any issues you experience.

Other enhancements and UX improvements

  • Options: k6 will now warn you on unrecognised configuration JS options in most cases instead of just silently ignoring them. (#1919)
  • error_code: the tag error_code should now be set more accurately in some cases. (#1952)
  • TLS: dropped support for SSLv3 encryption. This was dropped by Go, but now we no longer consider ssl3.0 a valid value for the tlsVersion k6 option. Thanks @codebien! (#1897)

Bugs fixed!

  • Arrival-rate executors could in some cases report twice as many used VUs than what was actually true. (#1954 fixed by #1955)
  • In cases of an error while reading the response body, the newly added responseCallback in v0.31.0 would be evaluated with the returned status code, while the reported one would be 0, as the response errored out and k6 does not return incomplete responses. Now responseCallback will also receive a 0 status. (#1962)
  • Fix Kafka output not being usable with the InfluxDB format after v0.31.0 changes. (#1914)
  • Error out with a user friendly message if ramping-vus executor would鈥檝e not run a single iteration instead of just doing nothing. (#1942)


Breaking changes

Support for ArrayBuffer in all k6 JS APIs (#1841)

Continuing from k6 v0.31.0, we鈥檙e finalizing the transition to ArrayBuffer values for working with binary data. This release introduces some changes that might break scripts that relied on the previous array of integers or string result types, returned by some of our JS APIs. Specifically these cases now return ArrayBuffer instead: open(..., 'b'), HTTP response bodies for requests that specified responseType: 'binary' (including when http.batch() is used), crypto.randomBytes(), hasher.digest('binary') and encoding.b64decode().
The previous default behavior of returning string from encoding.b64decode() can be replicated with a new optional format argument and a value of "s": encoding.b64decode("5bCP6aO85by-Li4=", "url", "s").
Most of these shouldn鈥檛 cause issues if the script is simply passing the values to another k6 API (e.g. opening a file as binary and passing it to http.post()), but in other cases the script will need to be modified to wrap the ArrayBuffer in a typed array view and use that API instead.

Deprecating official 32-bit binary releases (#2000)

We have stopped offering official builds for 32-bit Windows and Linux binaries, as they were causing issues in some cases, and users were likely using them by mistake instead of necessity.

Moved repo and renamed k6 Go module paths to go.k6.io/k6 (#2010)

We moved the repository location from GitHub - grafana/k6: A modern load testing tool, using Go and JavaScript - https://k6.io to GitHub - grafana/k6: A modern load testing tool, using Go and JavaScript - https://k6.io. Instead of also moving the Go module paths to the new repo location, we decided to use custom ones with our own domain, for more control. This will be a breaking change for all xk6 extensions, since they import parts of k6 by source to register themselves.

New .deb and .rpm repositories

We already mentioned this in the v0.31.0 release, but because of the Bintray shutdown, we had to move our .deb and .rpm repositories. They are now located at dl.k6.io, and you can use the updated installation instructions to transition to them.