Presence sounds like the easiest feature in a chat app. It's a green dot. But that dot has to be right for 100 million people, it changes every time someone closes a laptop lid, and every change has to reach everyone who can see it. In this lab you'll design a presence system from a blank page, modelled on a chat product like Discord's. You'll find that the hard part isn't storing the dot. It's telling people when it changes.
The brief
You're building the "who is online" layer for a chat product organised into servers (communities) and friend lists. Users open the app on a phone, a desktop app or a browser tab. Next to every name in a member list or friend list there is a status: online, idle, do not disturb, or offline. Some users also show an activity, like "Playing a game" or "Listening to a song".
People use presence to decide whether to message someone, whether to jump into a voice channel, and whether a community feels alive.
In scope for this lab:
- Tracking whether each user is connected, across all their devices.
- Showing status for friends and for members of the servers you're looking at.
- Pushing changes to the people who should see them.
- Custom status and current activity.
Out of scope:
- Sending messages, voice and video. Assume a separate chat service exists.
- Typing indicators. They use similar machinery but are even more short-lived.
- Notifications to offline phones.
Requirements
Functional
- When a user connects, they appear online to their friends and to the servers they belong to.
- When a user disconnects or goes quiet, they appear offline (or idle) within a short time.
- A user can set a status manually: online, idle, do not disturb, invisible.
- A user can have an activity ("Playing X") that others can see.
- A client opening a server's member list sees the current status of the visible members, and then sees changes live.
- Invisible users appear offline to everyone else, but can still use the app.
Non-functional
- Fresh: a status change should reach watchers within about 5 seconds in normal conditions. Going offline after a crash can take up to about 60 seconds.
- Scalable fan-out: a server can have 1 million members. One person going online must not cost a million messages.
- Cheap per update: presence changes far more often than messages do. It has to be the cheapest thing in the system.
- Available, not exact: a wrong dot for a few seconds is fine. Presence being down should never stop people chatting.
- Privacy: invisible must really look offline. No leaks through activity or "last seen" fields.
That fourth one matters a lot. Presence is a soft state system. It's allowed to be a little wrong, it rebuilds itself from live connections, and it never needs to survive a restart on disk. That frees you from almost every expensive tool you'd reach for with real data.