Skip to content

Performance Benchmarks

Every gate run measures end-to-end performance using Playwright (headless Chromium) against a live Node.js server on a random port. Each scenario runs for 3 seconds of sustained load. Web Worker transport and pako compression are enabled (defaults).

Latest results

Loading benchmark data...

Throughput over time

Median latency over time

Main-thread impact: Worker vs no-worker

Main-thread blocking over time

Console errors & warnings over time

What's measured

Each benchmark connects a real browser client (datasole IIFE bundle in headless Chromium) to a live Node.js server via WebSocket and runs sustained load for 3 seconds:

ScenarioDescription
RPC echoSequential ds.rpc(TestRpc.Echo, payload) — full round-trip latency (wire name still echo)
RPC concurrent10 concurrent ds.rpc() calls per batch — multiplexed throughput
RPC small payloadds.rpc() with a tiny JSON body (<256 B, below compression threshold)
RPC large JSONds.rpc() with randomized JSON (~1 KB, above compression threshold) — exercises pako
Binary frame streamingServer pushes 1 KB binary-like frames at max rate — simulates audio/video metadata streaming
Two-way low-latency emitClient emits, server echoes — measures full round-trip at emit speed (game ticks, trade confirms)
Server event receiveServer broadcasts at max rate, client counts received events
Live state syncServer mutates state rapidly, client receives JSON Patch diffs
Client event emitClient fires ds.emit() in a tight loop — fire-and-forget throughput
CRDT incrementClient increments a PN counter rapidly — CRDT op throughput
Mixed workloadAlternating RPC, emit, and add — combined throughput under mixed load

Additionally, 6 main-thread comparison benchmarks run each workload twice (with and without Web Worker transport) and measure Long Tasks, rAF jitter, and jank frames to quantify the off-main-thread benefit.

Every benchmark also records the number of browser console errors and warnings emitted during the test. These are first-class correctness indicators — any non-zero count under sustained load signals a runtime issue (unhandled rejection, deprecation, failed assertion, etc.) that should be investigated.

All benchmarks run in isolation (separate Playwright process, own browser instance) as part of the CI gate on every push to main.