Presence Channels
Presence channels build on standard channels by letting every subscriber know who else is in the channel. When someone joins, leaves, or updates their metadata, all members are notified with the full, current member list.
This is useful for chat rooms, collaborative documents, multiplayer games, or any feature where users need awareness of one another.
Each member has two fields:
uid— a unique user identifier, set via theuidtoken claim (required for presence channels)umd— optional user metadata (name, avatar, status, etc.), set via theumdtoken claim
Presence channel names must have a presence. prefix.
Limits
Every time a member joins, leaves, or updates their metadata, all members receive the full member list. Because of this, there is a size constraint on the channel.
The sum total size of all member payloads ({"uid":"...","umd":"..."}) must not exceed 100KB. There is no fixed user count limit — capacity depends on how much data each member carries. For example:
- ~100 members with 1KB of
umdeach - ~800 members with minimal
umd(~128 bytes each)
Attempting to subscribe when the channel is at capacity returns a PRESENCE_CHANNEL_CAPACITY_REACHED error.
Subscribe
Once connected with a token authorizing subscribe on a presence channel, subscribe by sending a message on the WebSocket:
> {"event":"hotsock.subscribe", "channel":"presence.live-chat"}
You'll receive a hotsock.subscribed message with the current members list in data and your own uid/umd in meta:
{
"event": "hotsock.subscribed",
"channel": "presence.live-chat",
"data": {
"members": [{ "uid": "Jim", "umd": null }]
},
"meta": { "uid": "Jim", "umd": null }
}
When another member joins
When Dwight subscribes from another connection, he receives his own hotsock.subscribed message with both members listed. You receive a hotsock.memberAdded message:
{
"event": "hotsock.memberAdded",
"channel": "presence.live-chat",
"data": {
"member": { "uid": "Dwight", "umd": null },
"members": [
{ "uid": "Jim", "umd": null },
{ "uid": "Dwight", "umd": null }
]
}
}
member— the member who just joinedmembers— the full, current member list (including the new member)
Duplicate connections with the same uid
If a user connects from a second device or browser tab with the same uid, the hotsock.memberAdded event is suppressed since they're already in the member list. However, if the new connection has different umd, a hotsock.memberUpdated event is sent so other members learn about the metadata change. If the umd is the same, no event is sent.
Member Updated
When a member's umd changes, all members (including the one who made the change) receive a hotsock.memberUpdated message:
{
"event": "hotsock.memberUpdated",
"channel": "presence.live-chat",
"data": {
"member": { "uid": "Dwight", "umd": { "status": "away" } },
"members": [
{ "uid": "Jim", "umd": null },
{ "uid": "Dwight", "umd": { "status": "away" } }
]
}
}
member— the member whose metadata changedmembers— the full, current member list reflecting the update
This event is triggered in two scenarios:
- Explicit update — a client sends a
hotsock.umdUpdatecommand targeting a presence channel subscription. This requires theumdUpdatechannel directive in aumd-scoped token. - Duplicate
uidwith differentumd— a second connection subscribes with the sameuidbut differentumd(see above).
This is useful for status indicators, typing notifications, or any per-user state that changes during a session without requiring a reconnect.
Unsubscribe
To leave a presence channel, send a hotsock.unsubscribe message:
> {"event":"hotsock.unsubscribe", "channel":"presence.live-chat"}
Remaining members receive a hotsock.memberRemoved message:
{
"event": "hotsock.memberRemoved",
"channel": "presence.live-chat",
"data": {
"member": { "uid": "Dwight", "umd": null },
"members": [{ "uid": "Jim", "umd": null }]
}
}
member— the member who leftmembers— the remaining member list
When a WebSocket connection disconnects, hotsock.unsubscribe is called automatically for all subscribed channels, so remaining members are always notified.
Event Summary
| Event | When | Delivered to |
|---|---|---|
hotsock.subscribed | You subscribe to the channel | You only |
hotsock.memberAdded | A new uid joins | All existing members (not the joiner) |
hotsock.memberUpdated | A member's umd changes | All members (including the updater) |
hotsock.memberRemoved | A member leaves or disconnects | All remaining members |
All hotsock.memberAdded, hotsock.memberUpdated, and hotsock.memberRemoved messages include both the affected member and the full current members list. You can always replace your local member list with the members array from these events to stay in sync.
If you're building with JavaScript, hotsock-js handles all of the above automatically, including maintaining a local member list that stays in sync with the channel.