Design a chat app with presence

Messages in the same order on every phone, never shown twice after a dropped connection, and a green dot that stays cheap when ten million people are online.

Should a chat app use WebSockets or long polling?

Use a long-lived connection, a WebSocket on the web and the platform socket on a phone, because the server has to push a message the moment it is stored. Polling asks the database the same empty question over and over: at two-second polls, ten million online users make five million queries a second to deliver about seventy thousand messages. Long polling is a fallback for networks that block WebSockets, not the design. Either way the client still keeps a cursor, so it can ask what it missed after a reconnect.

How do you keep messages in order in a group chat?

Give every conversation one owner that hands out a sequence number, 1, 2, 3, as each message arrives, and have every client sort by that number. Wall-clock timestamps from different servers disagree by milliseconds or seconds, so ordering by them can put a reply before its question. The sequence is the order the owner received the messages, which may differ from the order people pressed send, but it is one order that every device agrees on.

How do you stop a message being delivered twice?

Make the send idempotent: the client invents a message id before it sends, and the server remembers which sequence number each id got. A resend after a dropped connection gets the old number back and stores nothing new. On the receiving side the client keeps the highest sequence number it has shown and ignores anything at or below it, so a server that pushes a message again after a reconnect does no harm.

How does the online indicator work at scale?

Each client sends a heartbeat every 30 seconds or so, and the server stores a key per user with a time to live of about three heartbeats. The user is online while the key exists. Friends are told only when the state changes, and only the friends who are online and looking, because telling every friend on every heartbeat is tens of millions of pushes a second for a prompt this size.

Where are chat messages stored?

In a store partitioned by conversation and sorted by sequence number, which is the shape of a wide-column store such as Cassandra or HBase: one partition per chat, messages in order inside it. Reading everything after a cursor is one range read. At fifty million daily users sending forty messages each, that is about 400 GB of new messages a day.