STANDARDwalkthrough
Presence Service
How do we show green dots for 500M online users without melting the pub/sub layer? The naive approach broadcasts every status change to every contact.
At 500M users coming online over 10 minutes during morning peak, that is presence events per second, which overwhelms any pub/sub system. We chose lazy presence (not eager broadcast): we store each user's status in Redis with a key presence:user_id, value = status, last_seen, server_id, and a 60-second TTL.
“A user with 500 contacts going online triggers 500 push notifications.”
The client sends a heartbeat every 30 seconds to refresh the TTL. If the heartbeat stops (app closed, network lost), the key expires and the user is implicitly offline.
We only push presence changes to users who are actively viewing a chat with that contact. When User A opens a conversation with User B, the client subscribes to B's presence channel.
When B's status changes, only subscribers get notified, not all 500 contacts. Why not store presence in the database?
Because presence is ephemeral: it changes every time a user opens or closes the app. Writing 16.7M heartbeats/sec to MySQL would saturate the write pipeline.
Redis handles this with in-memory writes and auto-expiry via TTL. Trade-off: presence accuracy has a 30-60 second lag (heartbeat interval + TTL), but users tolerate 'last seen 1 minute ago' over perfectly real-time status.
Related concepts