Choosing Between Subscriptions, Presence, Broadcast, Room, and Push
These five features can look similar at first because they all deliver updates quickly. They solve different problems.
Short Version
| If you need... | Use |
|---|---|
| Database changes to appear automatically in the UI | Subscriptions |
| A list of who is online right now, plus lightweight status | Presence |
| Arbitrary messages between currently connected clients | Broadcast |
| Server-authoritative real-time state with validation and deltas | Room |
| Notifications to registered devices, even outside the active app session | Push Notifications |
Comparison
| Primitive | Mental model | Source of truth | Who sends updates? | Reaches only active socket clients? | Best for |
|---|---|---|---|---|---|
| Subscriptions | "The database changed." | Database rows/documents | Database writes trigger events automatically | Yes | Live feeds, dashboards, document viewers |
| Presence | "Who is here right now?" | Ephemeral channel presence state | Clients track/untrack their current state | Yes | Online indicators, typing, cursors, lobby presence |
| Broadcast | "Send this event to everyone connected here." | No built-in state | Clients or server publish event payloads | Yes | Chat events, collaboration signals, transient notifications |
| Room | "The server owns the state." | Room shared/player/server state | Clients send actions; server mutates state | Yes | Multiplayer games, trusted collaboration, auctions, voting |
| Push | "Notify this device." | Registered device tokens in KV + FCM delivery | Server only | No | Mobile/web notifications, re-engagement, background delivery |
How to Think About Each One
Subscriptions
Use Subscriptions when the thing you care about is already stored in the database. The database is the source of truth, and the realtime layer simply delivers change events to clients.
- Think: "show the latest posts, comments, orders, or metrics without polling"
- Good fit:
onSnapshot()on a table, query, or document - Not a fit: arbitrary chat events that are not backed by a row change
Presence
Use Presence when you want to know who is connected to a channel right now and attach a small amount of ephemeral metadata.
- Think: "who is online", "who is typing", "where is the cursor"
- Good fit: user status, collaborator cursors, game lobby player presence
- Not a fit: authoritative game rules or durable shared state
Presence often uses authenticated identity, but it is not an auth feature. Auth answers "who are you?" Presence answers "are you here right now?"
Broadcast
Use Broadcast when you want to send arbitrary event payloads to connected clients without building full server-owned state.
- Think: "someone sent a chat message", "flash this toast", "start animation now"
- Good fit: transient messages and lightweight pub/sub
- Not a fit: trusted state transitions that must be validated on the server
Broadcast is different from Push. Broadcast goes over the active realtime connection. Push goes through FCM to registered devices.
Room
Use Room when the server must own the rules and state. Clients do not write state directly. They send actions, the server validates them, mutates room state, and connected clients receive deltas.
- Think: "the game server decides", "the collaboration server resolves updates", "bids must be enforced centrally"
- Good fit: multiplayer, voting, auctions, high-trust collaboration
- Not a fit: simple "who is online" or "send this event to the channel" cases
Room can model participant state, so it can sometimes absorb room-scoped presence. It is still a heavier primitive than Presence, and it is not the default choice for lightweight online indicators.
Push Notifications
Use Push when you need delivery to a device, not just to an active socket connection.
- Think: "notify the user even if the app is backgrounded or not currently open"
- Good fit: mentions, order status alerts, reminders, marketing notifications
- Not a fit: low-latency in-app collaboration events between currently connected users
Push is server-initiated and routes through FCM. It is not a WebSocket channel.
Common Confusions
"Is Subscriptions really a database feature?"
Yes. It is delivered through the realtime layer, but conceptually it is a database change feed.
"Is Presence basically auth?"
No. Presence depends on identity and channel access rules, but its job is tracking current connection state.
"Is Broadcast the same as Room?"
No. Broadcast relays messages. Room owns and validates state.
"Can Room replace Presence?"
Sometimes inside a room-centric app, yes. In general, Presence is the simpler fit for lightweight online state.
"Is Push just another kind of Broadcast?"
No. Push targets registered devices through FCM and can reach users outside the current realtime session.
Typical Combinations
Chat App
- Subscriptions: message list backed by the database
- Presence: online and typing indicators
- Broadcast: transient typing or read-receipt events
- Push Notifications: new message alerts when the app is not active
Multiplayer Game
- Room: authoritative match state and actions
- Presence: optional lobby-level online indicators
- Push Notifications: match invites or turn reminders outside the live session
Decision Checklist
Ask these questions in order:
- Is the source of truth already in the database? Use Subscriptions.
- Do you only need to know who is connected and their lightweight status? Use Presence.
- Do you need to relay arbitrary in-session events without server-owned state? Use Broadcast.
- Must the server validate actions and own the live state? Use Room.
- Must the update reach a device even when the app is not actively connected? Use Push Notifications.