Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gatling/gatling.io-doc/llms.txt

Use this file to discover all available pages before exploring further.

WebSocket is a full-duplex communication protocol that keeps a persistent TCP connection open between a client and a server, enabling either side to push data at any time. Real-time dashboards, collaborative editing tools, live auction platforms, and multiplayer games all rely on WebSockets for low-latency, bidirectional communication. Gatling’s built-in WebSocket support lets you connect, send messages, check inbound frames, and handle unsolicited server-pushed messages — all within the same virtual-user model you use for HTTP testing.
The code examples in this guide use the Java SDK. The same concepts and method names apply to the Kotlin and Scala SDKs.

Prerequisites

  • Gatling version 3.13 or higher
  • Clone gatling/devrel-projects and navigate to articles/websocketguide
  • Node.js (to run the demo WebSocket server)

The Demo Server

The guide uses a simple Node.js WebSocket server that accepts connections and sends back a random number of messages at random intervals between 0 and 1 second:
// server.js
const WebSocket = require("ws");

const wss = new WebSocket.Server({ port: 8765 });

wss.on("connection", (ws) => {
  const messageCount = Math.floor(Math.random() * 5) + 1;

  const sendMessages = (remaining) => {
    if (remaining === 0) return;
    const delay = Math.random() * 1000;
    setTimeout(() => {
      ws.send(`Message ${messageCount - remaining + 1}`);
      sendMessages(remaining - 1);
    }, delay);
  };

  sendMessages(messageCount);
});

console.log("WebSocket server running on ws://localhost:8765");
Start the server:
node server.js

Writing the Simulation

Create the Scenario

The scenario below connects to the WebSocket server, waits for a specific first message, and then processes remaining buffered messages:
import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

public class WebSocketSample extends Simulation {

  HttpProtocolBuilder httpProtocol =
      http.baseUrl("http://localhost:8765");

  ScenarioBuilder scn = scenario("WebSocket Test")
    .exec(
      // Open the WebSocket connection
      ws("Connect").connect("/"),

      // Wait for and check the first message
      ws("Receive First Message")
        .await(5)
        .on(ws.checkTextMessage("Check Message 1")
          .check(bodyString().is("Message 1"))),

      // Process any remaining buffered inbound messages
      ws("Process Remaining")
        .processUnmatchedMessages((messages, session) -> {
          messages.forEach(m ->
            System.out.println("Unmatched: " + m.message()));
          return session;
        }),

      // Close the connection cleanly
      ws("Close").close()
    );
Key components explained:
ComponentDescription
ws("name").connect("/")Opens a WebSocket connection to the path
.await(seconds).on(check)Blocks and waits up to N seconds for a matching inbound message
ws.checkTextMessage("name").check(...)Defines a check to apply against text frames
processUnmatchedMessages(...)Handles buffered messages that were not matched by any explicit check
ws("name").close()Sends a close frame and tears down the connection

Inject a Single User for Verification

Always verify your scenario works correctly with a single virtual user before ramping up:
  {
    setUp(
      scn.injectOpen(atOnceUsers(1))
    ).protocols(httpProtocol);
  }
}

Scaling Up

Once the single-user run succeeds, increase the injection profile to simulate realistic concurrent WebSocket connections:
setUp(
  scn.injectOpen(rampUsers(500).during(60))
).protocols(httpProtocol);

Running the Test

1

Place the simulation in your project

Copy the simulation class into src/test/java/ (or the appropriate source directory for your build tool).
2

Run with Maven

mvn gatling:test
3

Review the report

Gatling prints a report URL to the terminal when the simulation completes. Open it to review connection metrics, response times for .await() checks, and error rates.

Monitoring WebSocket Connections in Reports

WebSocket simulations benefit from Gatling Enterprise Edition’s Connections tab, which shows:
  • TCP connection open/close rates — confirms that virtual users are establishing and tearing down connections as expected
  • Concurrent connections over time — helps correlate performance changes with connection counts
  • TLS handshake times — relevant when testing wss:// endpoints

Best Practices

Use secure WebSockets

In production, your WebSocket endpoint should use wss:// (TLS). Update baseUrl to https:// (Gatling uses wss:// automatically when the base URL is HTTPS) and add .disableCaching() if needed.

Buffer asynchronous messages

Real WebSocket servers may push messages at any time. Use processUnmatchedMessages to drain the buffer and avoid memory growth during long-running simulations.

Add realistic pauses

Insert .pause() calls between sends to model the natural pacing of your application’s clients. Without pauses, virtual users may flood the server with far more messages per second than a real client would send.

Include error handling

Use exitBlockOnFail() around the connection and initial check so that virtual users who cannot establish a connection do not continue executing the rest of the scenario.

Further Reading

Build docs developers (and LLMs) love