Real-Time APIs · Scaling Real-Time Systems
Presence, Typing Indicators and Ephemeral State
Track who's online without overwhelming the system.
Presence (online/offline/last seen) and typing indicators are ephemeral, high-frequency and fan out widely. Track presence with heartbeats + TTLs (Redis keys expiring after missed heartbeats), handle multiple devices per user, debounce changes (don't broadcast every reconnect flap), and only send presence to interested parties (contacts or room members currently viewing). Typing indicators should be throttled and never persisted.
Ephemeral vs durable signals
| Signal | Frequency | Storage | Audience |
|---|---|---|---|
| Presence | On change (debounced) | TTL keys | Contacts / room members |
| Typing | Throttled (≤ 1 per 3 s) | None | Current room viewers |
| Read receipts | Per message/batch | Durable | Conversation members |
| Last seen | On disconnect | Durable (coarse) | Privacy-controlled |
Presence with Redis
SET presence:user:42:device:abc 1 EX 60 # refreshed by heartbeat every 25 s
online(user) = EXISTS any presence:user:42:device:* (or a set with per-device expirations)
Broadcast 'online' only after 5 s stable; 'offline' after 30 s without devices (debounce flaps)
Typing: client sends at most every 3 s while typing; server relays to room, no storage
Common pitfalls
- Broadcasting presence to every user.
- Storing typing events.
- Flapping online/offline on mobile network changes.
Key points
- Heartbeats + TTLs
- Debounce and scope fan-out
- Throttle typing; don't persist
Further reading: Ably documentation (presence and history concepts)
Practice questions
Why debounce presence changes?
Answer
Mobile networks cause rapid disconnect/reconnect flaps; broadcasting each would spam contacts and waste resources.
How do you handle presence for users with multiple devices?
Answer
Track presence per device with TTLs; the user is online if any device is active, offline when the last device expires.
Open in the app to mark lessons complete, take notes and track your progress.