System Design
Presence Service
Design an online presence and last-seen service like WhatsApp or Slack.
Functional requirements
- Clients send periodic heartbeats while a user is active; a user whose heartbeats stop is shown offline within a bounded window (e.g., 30 seconds) with no explicit sign-off.
- Any user can fetch a contact's current status (online, away, or offline) and, when offline, a last-seen timestamp (e.g., 'last seen today at 14:32').
- A client subscribes to live status changes for the contacts it is currently displaying (e.g., an open chat list of 50 people) and receives a push when any of them changes.
- Users can set a manual status that overrides the automatic one (e.g., 'Do not disturb' in Slack) and can hide their last-seen from non-contacts.
- A user signed in on several devices is online if any device is active and goes offline only when the last device falls silent.
Non-functional requirements
- Status reads are latency-sensitive: p99 under 100ms for a status lookup, and a status change reaches subscribed viewers within 5 seconds.
- Availability over consistency: presence is best-effort, so a status may be stale by a few seconds and a brief false online after a disconnect is fine, but a manual do-not-disturb or invisible setting must never be overridden by a heartbeat.
- Durability is split: live online state is ephemeral and may be lost on a node restart (clients re-heartbeat within seconds), but last-seen timestamps and manual status settings must survive restarts.
- A mass reconnect (e.g., a network blip that makes 20% of clients reconnect within a minute) must not cascade into an outage or a push storm.
- Privacy: status and last-seen are served only to viewers the target permits, enforced by the service rather than the client.
Scaling & constraints
- 500M monthly active users; 100M concurrently online at daily peak, each holding one persistent connection to a gateway fleet of ~10,000 servers (~10,000 connections each).
- Devices heartbeat every 10 seconds, so ~10M heartbeats per second at peak; each heartbeat is under 100 bytes.
- Presence state per user is tiny (~50 bytes: status, last-seen, device count), so 500M users x 50B ≈ 25GB of live state.
- Users have ~200 contacts on average but display only 20-50 at a time; a typical status change must reach ~30 subscribed viewers, while a large Slack workspace admin may have 50,000.
- Flapping is common: mobile clients on poor networks toggle online and offline up to 20 times per minute, and about 5% of all connections churn every minute.
- A network blip or app update can trigger 20M reconnects within 60 seconds, each producing a connect event and a status fetch for the user's visible contacts.
Out of scope
- Chat message delivery and storage.
- Authentication, account management, and the contact list service itself.
- Typing indicators and read receipts.
- Mobile push notifications to offline users.
Sign in to save your progress
AI design evaluation
Get a score, what your board does well, what to fix first, and what an interviewer would ask next.
Sign in to get AI feedback on your design.