Real-Time Presence System

Online status, last seen and typing indicators

Design the service behind the green dot: who is online, when they were last seen and who is typing, pushed within seconds to the people looking, for tens of millions of connected users.

Overview

A presence system answers one question for the people you talk to: are you here right now? It shows a dot (online, idle, offline), a 'last seen' time, and a 'typing' hint in a conversation. Chat apps, collaboration tools and multiplayer games all have one.

Presence is small data that changes all the time. The status of one user is a few bytes, but it changes whenever a phone locks, a laptop sleeps or a train enters a tunnel, and every change could interest hundreds of contacts. The two hard parts are knowing that someone left (devices often disappear without saying goodbye) and telling only the people who care, without multiplying every change by the size of the contact list.

Presence is also allowed to be a little wrong. A dot that turns grey ten seconds late hurts nobody; a server that falls over trying to be exact hurts everyone. The design leans on that: keep presence in memory, never in a database on the hot path, and drop it rather than queue it when things go badly.

Questions to ask first

  • How many users, how many connected? — 200 million daily users; 50 million connected at peak
  • How many contacts per user? — About 200 on average; group channels can have thousands of members
  • How fresh must the dot be? — Online within about 2 seconds; offline within about 90 seconds of a silent drop
  • Several devices per user? — Yes: a user is online if any device is
  • Typing indicators and last seen? — Yes; typing is never stored, last seen is
  • Privacy? — Users can hide last seen and status from everyone or from non-contacts; blocked users see nothing

What you will be able to do

  • Define online, idle and offline for a user with several devices.
  • Detect silent disconnects with heartbeats, and hide flapping with a grace period.
  • Explain why subscribe-on-view fan-out beats pushing to every contact, with numbers.
  • Keep typing indicators and presence out of the database, and write last seen sparingly.
  • Enforce privacy settings before a status leaves the server.

Key concepts

  • Per-device sessions
  • Heartbeats and timeouts
  • Grace period
  • Connection gateways
  • Subscribe on view
  • Pub/sub channels
  • Ephemeral state
  • Last seen
  • Privacy filtering
  • Reconnect storms

Functional requirements

  • Show each user as online, idle or offline, combining all their devices
  • Show last seen for offline users, subject to their privacy setting
  • Push status changes to users who currently have that user on screen
  • Show and clear typing indicators in a conversation
  • Let a client fetch the current status of up to 100 users at once
  • Let users hide their status and last seen, and hide everything from blocked users

Non-functional requirements

  • A user coming online reaches watchers within 2 seconds at p99 (a target we chose)
  • A device that drops silently is shown offline within about 90 seconds (a target we chose)
  • A typing indicator appears within 500 ms and disappears on its own if the sender vanishes
  • Losing a presence server or gateway never blocks messaging; presence rebuilds from live connections
  • A hidden status or last seen never reaches a viewer who may not see it

Interview questions

  • How do you know a user went offline if their phone just loses signal?
  • Why not push every status change to every contact?
  • Would you use Redis TTL keys and expiry notifications for offline detection?
  • How do typing indicators work without storing anything?
  • How do you enforce privacy settings?
  • A whole gateway fleet restarts. What happens?
  • How do you show presence in a channel with 50,000 members?

Sign up free to read the full topic

More System Design topics

Start free on Cariara · Coding problems · System design studio