Presence events
Presence events are how Presence reports a client's lifecycle on a channel:
- arriving
- leaving
- going quiet
- changing its state
PubNub delivers them on the channel's -pnpres companion channel, through the same event listener you already use for messages and signals. This page explains:
- the five event subtypes delivered on the
-pnpreschannel, and what their payloads carry - the
activeandinactivechannel events, and why they're delivered elsewhere - how a channel's occupancy switches it between announce mode and interval mode
- how presence deltas add who changed to an interval event
- how
presenceTimeoutandheartbeatIntervaldecide when atimeoutevent fires
Every presence event requires you to enable Presence, which tracks who is online on a channel, on your keyset. If you track selected channels only, a presence rule must match the channel and include the event type, as described in Presence.
To receive the five -pnpres event subtypes, also enable receivePresenceEvents on the channel subscription. To receive active and inactive, subscribe to the keyset's Active Notice Channel, which collects channel-level events for the whole keyset.
For how presence data is enabled and delivered, and how it relates to occupancy and presence state, refer to Presence. For the subscription call and listener setup, refer to Receive presence events.
Event subtypes delivered on the -pnpres channel
| Subtype | Fires when |
|---|---|
join | A client subscribes to the channel |
leave | A client unsubscribes from the channel |
timeout | A client goes silent for longer than the channel's heartbeat timeout allows |
state-change | A client's presence state changes |
interval | The channel is in interval mode and reports occupancy on a fixed schedule |
Every presence event names the channel it happened on, carries the channel's current occupancy, and stamps a timetoken. Most also carry the uuid of the client whose presence changed, identified by User ID.
interval events are the exception: they describe the channel as a whole rather than one client, so they carry no uuid. A state-change event also carries a data field holding the state that changed.
The following illustrates the payload for each subtype that fires individually in announce mode:
- join
- leave
- timeout
- state-change
1{
2 "action": "join",
3 "channel": "chats.room1",
4 "occupancy": 3,
5 "uuid": "user123",
6 "timetoken": "17511946699655811"
7}
1{
2 "action": "leave",
3 "channel": "chats.room1",
4 "occupancy": 2,
5 "uuid": "user123",
6 "timetoken": "17511946699812340"
7}
1{
2 "action": "timeout",
3 "channel": "chats.room1",
4 "occupancy": 1,
5 "uuid": "user456",
6 "timetoken": "17511947001234567"
7}
1{
2 "action": "state-change",
3 "channel": "chats.room1",
4 "occupancy": 3,
5 "uuid": "user123",
6 "timetoken": "17511947895378127",
7 "data": {
8 "mood": "grumpy"
9 }
10}
Field names are typed per SDK, not platform-wide. For the exact shape your handler receives, refer to the API reference for your platform in Available SDKs.
Channel active and inactive events
Two more subtypes describe the channel as a whole rather than a single client. PubNub doesn't deliver them on -pnpres.
| Subtype | Fires when |
|---|---|
active | A channel gets its first occupant (occupancy goes from 0 to 1 or more) |
inactive | The last occupant leaves a channel (occupancy goes from 1 or more to 0) |
Your presence event listener doesn't receive active and inactive, because PubNub doesn't deliver them on the channel's -pnpres channel. PubNub publishes them as messages on the keyset's Active Notice Channel, which you set in the keyset's Presence configuration. That channel receives these events from every channel on the keyset.
To receive them, subscribe to the Active Notice Channel like any other channel. Clients get them only while subscribed. To fetch them later, enable Include presence events in Message Persistence settings and retrieve them from history.
Channel occupancy decides announce mode or interval mode
Below the Announce Max threshold, a channel emits individual join, leave, and timeout events. At or above it, the channel emits periodic interval events instead, while state-change stays individual in both modes.
Interval mode exists so a busy channel's presence traffic doesn't emit thousands of join, leave, and timeout events for ordinary churn. You configure the occupancy threshold and the interval's cadence per keyset in Presence Management, not in your application code. For the threshold's default and maximum values and the interval cadence limits, refer to API limits. To see what stays accurate on Here Now after a channel crosses that threshold, refer to Occupancy.
Presence deltas add who changed to an interval event
By default, an interval event carries only a total occupancy count. Suppressing individual join, leave, and timeout events is the whole point of interval mode.
Enabling Presence Deltas in Admin Portal adds three arrays to each interval event:
joinleavetimeout
Each array lists the User IDs that changed since the previous interval:
1{
2 "action": "interval",
3 "channel": "chats.megachat",
4 "occupancy": 27,
5 "timetoken": "17511947739621090",
6 "join": ["user123", "user88"],
7 "leave": ["user20", "user11"],
8 "timeout": ["user42"],
9 "hereNowRefresh": false
10}
The standard message payload size limit is 32 KiB. This includes the channel name and any metadata. An interval event's delta arrays count toward that limit alongside the rest of the payload. If the arrays would push the event over the limit, PubNub drops them and sets hereNowRefresh: true instead.
Treat that flag as a signal to call Here Now, since the deltas you needed didn't arrive. Refer to Get online users in a channel for more details.
Heartbeats decide when a timeout event fires
A timeout event depends on a per-client timer, not on network-level disconnect detection. PubNub SDKs set presenceTimeout to 300 seconds by default, which is how long PubNub waits without a heartbeat before marking a client offline. Anything that resets the timer before it expires keeps the client marked online. Letting it expire is what fires timeout.
Two settings control the timeout timer:
presenceTimeout(alsopresenceHeartbeatValueordurationUntilTimeoutin some SDKs) is the timer itself. It sets how long PubNub waits without a heartbeat before marking a client offline and emittingtimeout.heartbeatInterval(alsopresenceHeartbeatInterval) is how often the client sends a dedicated explicit heartbeat through the Presence Heartbeat API to reset that timer on demand. Explicit presence heartbeats are off by default in PubNub SDKs, becauseheartbeatIntervaldefaults to0.
Every subscribe call also resets the timer as an implicit heartbeat, whether or not heartbeatInterval is set. A client that's actively subscribing has already proven it's there, so leaving heartbeatInterval at its default works for most applications. Only a client that stops subscribing entirely drifts toward timeout.
Explicit heartbeats detect a disconnect sooner than implicit ones alone. A subscribe connection can sit idle for up to the platform's long-poll window before the SDK reissues it. A client that disconnects right after that window starts stays marked online until the rest of presenceTimeout also elapses. Setting heartbeatInterval shorter than that window closes the gap. Each heartbeat is a billable API call, and every connected client makes one on that schedule.
Set heartbeatInterval if your application needs to detect a disconnect quickly. Leave it at its default if an active user's own subscribe traffic already proves them present, as in most chat apps.
Some SDKs derive heartbeatInterval from presenceTimeout once you set presenceTimeout, instead of leaving it at its default. Check your SDK's configuration reference before assuming you get the default.
For the mechanics of implicit heartbeats and what a disconnect looks like to other clients, refer to Connection management. For the minimum values SDKs enforce on both settings, refer to API limits.
Presence timeout detection is local, not regional. It doesn't depend on which region a client connects through. PubNub SDKs don't actively poll a client's connectivity. A disconnect is detected only when a subscribe request times out or the next request fails. That's a property of the client's own connection, not of PubNub's monitoring.
Next steps
- Presence. How presence data is enabled and delivered, and how it relates to occupancy, state, and membership.
- Occupancy. What a
Here Nowresponse contains and why it stays accurate once a channel switches to interval mode. - Receive presence events. Subscribe to a channel with presence events enabled and register a listener.
- Get online users in a channel. Call
Here Nowto look up current occupancy on demand. - Set and get presence state. Attach and read the custom state that triggers
state-change. - Presence Management. Configure which channels and event types generate presence events.
- Connection management. Implicit heartbeats, reconnection, and what other clients see when you disconnect.
- API limits. Announce max, interval cadence, and heartbeat limits.