Warning
🐉 Experimental / pre-alpha software. Behavior may change without notice. 🐉
The wsmux server is a high-performance WebSocket multiplexer built on Bun.serve, supporting Polkadot JSON-RPC V1 and technologies dependent on legacy interfaces.
It multiplexes client sessions over shared streams, with nested operation isolation, per-client subscription management, caching, telemetry, and server-affinity routing.
wsmux supports an optional cross-upstream cache to reduce redundant JSON-RPC requests and upstream load.
cache:
enabled: trueWhen disabled, all requests bypass the cache.
Caching is configured per method:
cache:
methods:
chainHead_v1_header:
enabled: true # turn caching on/off for the method
max_entries: 100 # maximum number of cached responses retainedFor multiplexed methods like chainHead_v1_*, caching is applied per sequence of operations, not per raw request.
A cache entry consists of the initial started response plus the ordered stream of operation notifications. New clients replay the cached sequence and, if the operation is still active, attach to the live stream.
Although operations are shared, each client receives a filtered, rewritten view of the notifications (per-client subscription IDs), preserving logical isolation while reusing upstream work.
Conceptually, the multiplexing architecture looks like this:
Wsmux # load balancing: round-robin per upstream
├─ Upstream A # max_connections, WS load balancing: least-connections
│ ├─ WS-1 # max_clients_per_connection
│ │ ├─ SharedSubscription-1 # e.g. max_subscribers for chainHead_v1_follow
│ │ │ ├─ Client-1
│ │ │ └─ Client-2
│ │ └─ SharedSubscription-2
│ │ └─ Client-3
│ └─ WS-2
│ └─ SharedSubscription-1
│ └─ Client-4
└─ Upstream B ...- Wsmux
- The entry point that distributes client connections across upstreams using round-robin.
- Upstream
- Backend servers. Each maintains a maximum connection count and uses least-connections load balancing across its WebSocket connections.
- WS
- A single WebSocket connection to an upstream. Connections dynamically scale between a minimum and maximum defined by
min/max_connections. Themax_clients_per_connectionsetting limits the number of clients each connection serves. - SharedSubscription
- Multiplexed subscription streams (e.g.
chainHead_v1_follow), shared by multiple clients up to the configuredmax_subscribers. - Client
- An individual client session. Fully isolated logically but sharing the underlying WebSocket and subscription streams with other clients.
All settings (upstream servers, caching, rate limits, etc.) are defined in a YAML configuration file.
An example configuration is provided here: ./wsmux.config.yaml
Upstreams can reference a preset to enable a predefined set of JSON-RPC methods.
Presets are convenience bundles that define which methods an upstream is allowed to expose, combining legacy and V1 APIs as needed.
Available presets:
- polkadot_legacy
- Enables legacy Polkadot JSON-RPC methods (e.g. chain_*, state_*, author_*, system_*, subscriptions).
- polkadot_v1
- Enables Polkadot JSON-RPC V1 methods, including chainHead_v1_*, archive_v1_*, transaction_v1_*, and chainSpec_v1_*.
- polkadot
- A superset combining both polkadot_legacy and polkadot_v1.
Example usage:
upstream:
servers:
- name: stakeworld
url: wss://dot-rpc.stakeworld.io
presets: polkadotPresets act as an allowlist: only methods included in the resolved preset may be forwarded to the upstream.
Requests for methods not included in the upstream's preset are forwarded directly.
- wsmux assigns a temporary upstream ID to the request to avoid collisions between multiple clients
- The upstream response is rewritten to use the original client ID before sending back
- This works for standard requests, but not for subscriptions, which require dedicated multiplexing
This allows clients to call any method in a request-response fashion, even if it's not part of a preset.
To install dependencies:
bun installTo run the server:
bun startTo build the Docker image:
docker build -t wsmux .To run the Docker container:
docker run -it --rm \
-p 8181:8181 \
-v $(pwd)/wsmux.config.yaml:/usr/src/app/wsmux.config.yaml:ro \
-e WSMUX_CONFIG=/usr/src/app/wsmux.config.yaml \
-e WSMUX_LISTEN=:8181 \
wsmuxDeveloped by SO/DA zone.
❤️ Enjoy wsmux!