Skip to main content
The k6/websockets module implements the browser WebSocket API with additional k6-specific functionality like cookies, tags, and custom headers.
The k6/experimental/websockets module has been deprecated. Use k6/websockets instead.

Overview

This module uses a global event loop instead of a local one, which enables a single VU to handle multiple concurrent WebSocket connections. This improves performance compared to the older k6/ws module.

Key Difference from k6/ws

The main difference between k6/websockets and k6/ws is that this module uses a global event loop, allowing a single VU to have multiple concurrent connections, which improves performance.

Importing the Module

import { WebSocket } from 'k6/websockets';

API Reference

Classes and Methods

WebSocket(url, protocols, params)
constructor
Constructs a new WebSocket connection.Parameters:
url
string
required
WebSocket URL (e.g., wss://echo.websocket.org)
protocols
string | string[]
Optional protocol(s) to use
params
Params
Connection parameters (headers, cookies, compression, tags)

Instance Methods

WebSocket.close()
function
Closes the WebSocket connection.
WebSocket.ping()
function
Sends a ping frame to the server.
WebSocket.send(data)
function
Sends data through the WebSocket connection.Parameters:
data
string | ArrayBuffer | Blob
required
Data to send to the server
WebSocket.addEventListener(event, handler)
function
Adds an event listener for a specific event.Parameters:
event
string
required
Event name: 'open', 'message', 'error', 'close', 'ping', 'pong'
handler
function
required
Callback function to handle the event

Instance Properties

WebSocket.readyState
number
The current state of the connection. One of:
  • 0 - CONNECTING
  • 1 - OPEN
  • 2 - CLOSING
  • 3 - CLOSED
WebSocket.url
string
The URL of the connection as resolved by the constructor.
WebSocket.bufferedAmount
number
The number of bytes queued using send() but not yet transmitted.
WebSocket.binaryType
string
Controls the type of binary data received. Either "blob" (default) or "arraybuffer".

Event Handlers

WebSocket.onopen
function
Handler called when the connection is established.
WebSocket.onmessage
function
Handler called when a message is received.
WebSocket.onerror
function
Handler called when an error occurs.
WebSocket.onclose
function
Handler called when the connection is closed.
WebSocket.onping
function
Handler called when a ping is received.
WebSocket.onpong
function
Handler called when a pong is received.

Connection Parameters

Params Object

compression
string
Compression algorithm to use. Currently only "deflate" is supported.
jar
http.CookieJar
Cookie jar for the WebSocket connection. Uses the default VU cookie jar if not specified.
headers
object
Custom HTTP headers to include in the WebSocket handshake request.
headers: { 'X-MyHeader': 'k6test' }
tags
object
Custom metric tags for filtering results and setting thresholds.
tags: { k6test: 'yes' }

WebSocket Metrics

k6 automatically collects WebSocket-specific metrics:
MetricTypeDescription
ws_connectingTrendTime to establish connection
ws_session_durationTrendTotal session duration
ws_sessionsCounterTotal number of sessions
ws_msgs_sentCounterMessages sent
ws_msgs_receivedCounterMessages received
ws_pingTrendPing round-trip time

Examples

Multiple Concurrent Connections

This example shows how a single VU can run multiple WebSocket connections asynchronously:
import { randomString, randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.1.0/index.js';
import { WebSocket } from 'k6/websockets';

const sessionDuration = randomIntBetween(1000, 3000);

export default function () {
  for (let i = 0; i < 4; i++) {
    startWSWorker(i);
  }
}

function startWSWorker(id) {
  const ws = new WebSocket(`wss://quickpizza.grafana.com/ws`);
  ws.binaryType = 'arraybuffer';

  ws.addEventListener('open', () => {
    ws.send(JSON.stringify({ event: 'SET_NAME', new_name: `VU ${__VU}:${id}` }));

    ws.addEventListener('message', (e) => {
      const msg = JSON.parse(e.data);
      if (msg.event === 'CHAT_MSG') {
        console.log(`VU ${__VU}:${id} received: ${msg.user} says: ${msg.message}`);
      } else if (msg.event === 'ERROR') {
        console.error(`VU ${__VU}:${id} received:: ${msg.message}`);
      }
    });

    const intervalId = setInterval(() => {
      ws.send(JSON.stringify({ event: 'SAY', message: `I'm saying ${randomString(5)}` }));
    }, randomIntBetween(2000, 8000));

    const timeout1id = setTimeout(function () {
      clearInterval(intervalId);
      console.log(`VU ${__VU}:${id}: ${sessionDuration}ms passed, leaving the chat`);
      ws.send(JSON.stringify({ event: 'LEAVE' }));
    }, sessionDuration);

    const timeout2id = setTimeout(function () {
      console.log(`Closing the socket forcefully 3s after graceful LEAVE`);
      ws.close();
    }, sessionDuration + 3000);

    ws.addEventListener('close', () => {
      clearTimeout(timeout1id);
      clearTimeout(timeout2id);
      console.log(`VU ${__VU}:${id}: disconnected`);
    });
  });
}

k6/ws

Alternative WebSocket module with local event loop

Blob

Handle binary data in WebSocket messages

WebSocket Testing Guide

Learn WebSocket testing patterns

Metrics Reference

WebSocket metrics documentation

Build docs developers (and LLMs) love