What a WebSocket event should carry
A socket is a doorbell. It is not a second API.
The first version of a live UI sends the whole record on every change. The payload grows until it includes fields this viewer should not have, and the client merge becomes the authorization check. Both of those are the wrong place.
Send an id and a time
{ "type": "record.updated", "id": "rec_1842", "at": "2026-10-21T09:14:00+05:30" }
The handshake already checked the token and the room. On the event, the client refetches through the same HTTP handler the page used on load. That handler runs the row check again.
Leave these on HTTP
- other people's records, including a global tape
- message bodies
- anything a rules engine computed and the client might "correct"
Those responses have their own checks. A fan-out that includes them will eventually include them for the wrong tab.
Reconnect without a private replay
Reconnect with the same token if it is still valid, then refetch whatever was on screen. Do not keep a per-user buffer and replay it. If an event was missed, the refetch is the catch-up. A sequence number can tell the client that a gap happened. It should not be a tunnel for the missed body.
This stays true when the source of the change is a log such as Kafka. The browser holds a socket and a snapshot. The API still owns the data.
Topics Node.jsWebSockets