Every subscriber, every server
An order written through server 1 reaches dashboards connected to servers 2 and 3 within milliseconds.
The framework for AI era
Level 3 · ScaleArchitecture 06 of 13
WebSocket clients on any server, changes made on any server: Redis connects them.
Dashboards, apps and devices keep a WebSocket open to whichever server they reached. An API call answered by any server is published in Redis and pushed to every matching subscriber, on every server, within milliseconds.
Every request is drawn as it travels. Slow it down, pause, go step by step, or open the full canvas and zoom in.
Clients subscribe once, on any server. Dashboards, driver apps and screens open a WebSocket through the load balancer. Their subscriptions are kept in Redis.
The same steps as the diagram, in more detail.
A frontend or a device opens a WebSocket to port 38245, through the load balancer, and stays on the server it reached. It registers the events it wants: calls of an API, like the insert of orders, with conditions on the response, or custom events. Every subscription becomes a key in the internal Redis, which is how the other servers find it.
Requests keep flowing through the load balancer to the least busy server. A new order may be written by server 1 while the dashboards that want to see it are connected to server 2 or 3. No server needs to know where the subscribers are.
The call is published as an event in the internal Redis. Redis delivers it to every process that registered a matching subscription, on any server, and each one pushes it down the WebSockets it holds. A dashboard connected to server 3 sees an order written by server 1 within milliseconds.
Subscriptions carry conditions on the response and a list of fields to send. An event only goes where a condition matches, so servers without matching subscribers receive nothing, and clients only get the fields they asked for. Access is checked when the client subscribes, with the token of the right auth provider.
Besides database changes, custom code can emit WebSocket events of your own, like the position of a driver or the progress of a job. They travel the same way: through Redis, to every server holding a subscriber, with the same conditions and access checks.
When a server stops, the WebSockets it held close. The clients reconnect through the load balancer, which sends them to a healthy server, and register their subscriptions again. Events raised anywhere reach them through their new server.
An order written through server 1 reaches dashboards connected to servers 2 and 3 within milliseconds.
Conditions on the response decide who gets an event, and select sends only the fields a client needs.
Clients subscribe with a token of the right auth provider, and your code can accept or refuse each one.
Custom code emits custom WebSocket events, delivered with the same conditions and checks.
Clients of a stopped server reconnect to another one and subscribe again. Nothing to configure.
The WebSocket server is part of API Maker, built on uWebSockets.js, and Redis is the one you already run.
Plain VPS from any provider, or your own servers, with Ubuntu 22.04 LTS. Sizes are a starting point: measure and adjust.
Runs
Ports
Runs
Ports
Many long-lived connections: raise the limit of open files (ulimit -n) of the API Maker process.
Runs
Ports
Runs
{ "objType": "REGISTER", "onEvents": [{ "eventType": "INSTANCES", "apiName": "GEN_POST_BULK_INSERT", "instance": "shop", "database": "public", "collection": "orders", "condition": { "conditionType": "RESPONSE", "criteria": { "store": "42" } }, "select": { "id": 1, "items": 1, "total": 1 }, "getEventData": true }]}Sent over wss://api.example.com with the token of the client. Every insert of an order of store 42, through any server, is pushed to it.
No. A WebSocket is one long connection, so it stays on the server it reached by itself. Events raised on any other server reach it through Redis.
Calls of the generated APIs of your tables, like the insert or the update of orders, with conditions on the response and the fields to receive. Also calls of custom APIs, system APIs and third-party APIs, and custom WebSocket events emitted by your code.
A client connects with the token of an auth provider and each WebSocket event accepts the tokens of the provider chosen for it. Custom code can also decide, for each client, whether it may subscribe.