Design a one-to-one chat system
Company: Anthropic
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Technical Screen
Design a **one-to-one (1:1) chat system** for a web application — the kind of direct-messaging feature where two users can send each other text messages in real time, see whether the other person is online, and reliably receive messages that arrived while they were away.
Walk through the end-to-end design and be ready to go deep on each piece. In particular, address:
- How clients connect and exchange messages in **real time**.
- How the system determines whether a user is **online** (presence).
- How to handle delivery when the **recipient is offline**.
- How to **store** messages, conversation metadata, unread counts, and delivery state.
- How to preserve **message ordering** and avoid **duplicate sends**.
- Where **Redis** versus **Kafka** belong in this system, and why.
- The **core ideas behind Kafka**, and when it is or is not a good fit for the chat-delivery path.
```hint Where to start
"Real time" rules out the client having to ask for new messages — the server has to be able to push to the recipient. Enumerate the browser-to-server transport options you know and weigh them against that requirement (which support server→client push? client→server sends? at what per-message cost?). Which single transport fits both directions?
```
```hint Presence
Online/offline isn't permanent state — a user can vanish without telling anyone (closed tab, dead network). What property does that give "online" status, and what naturally happens to such state if you stop refreshing it? Also ask: with many chat servers, where does presence have to live so any server can read it?
```
```hint Durability before delivery
A send touches two things: a durable record and the recipient's screen. The order you do them in decides what a mid-send crash loses. Reason about each ordering and what the sender's "sent" acknowledgement should be allowed to mean. Which component should be the source of truth for history?
```
```hint Ordering & idempotency
Two questions hide here. (1) If two messages land almost simultaneously, what decides their order — and why are client clocks a poor choice? (2) Networks make clients retry sends; how could a retry create a second copy, and what would let the server recognize "I've seen this exact send before"?
```
```hint Redis vs Kafka
Sort the system's jobs into two buckets: the online critical path (must be fast, state is short-lived) versus durable asynchronous work that downstream consumers do later (indexing, analytics, moderation, notifications). Which tool suits each bucket? And probe the gap: if a pub/sub subscriber is offline when a message is published, what happens to that message — and what does that imply about using it as your store of record?
```
### Constraints & Assumptions
State these explicitly (or surface them as clarifying questions) and design to them:
- **Single device per user.** Each user is active on at most one browser/web client at a time, so a user has at most one live connection. (Call out how multi-device sync would change presence and delivery if asked.)
- **1:1 only.** Group chat, channels, and broadcast are out of scope.
- **Text messages.** Media/attachments, voice, and video are out of scope; mention how large media would change the storage and transfer path if asked.
- **Real-time but durable.** Online messages should feel instant (sub-second), and messages must survive server crashes and offline recipients.
- **No end-to-end encryption requirement** unless the interviewer raises it; assume transport-level TLS.
- Pick a working scale to make numbers concrete (e.g. low millions of users, tens of thousands concurrent connections) rather than leaving it unbounded.
### Clarifying Questions to Ask
- Is this strictly single-device, or do we need multi-device fan-out and read-state sync across a user's sessions?
- What ordering guarantee is expected — per-conversation ordering only, or anything stronger?
- Do we need delivery and read receipts (sent / delivered / read), or just message delivery?
- Are offline **push notifications** (Web Push / mobile) in scope, or only in-app catch-up on reconnect?
- What retention is required for message history (forever, N days), and is full-text search over messages needed?
- Roughly what scale — total users, daily active, peak concurrent connections, messages/sec — and single-region or multi-region?
### What a Strong Answer Covers
- A clear **real-time transport choice** with justification against the alternatives, plus how connections are authenticated and upgraded.
- A **presence design** that is shared across servers and self-heals when a connection dies — not just an in-memory flag on one server.
- A **send path** that takes an explicit, defended position on persist-vs-deliver ordering and on what the sender ack means.
- A **data model**: messages, conversations, per-user read/unread state, and a delivery/read state machine (sent → delivered → read), including whatever column(s) the ordering scheme depends on.
- A correct **ordering strategy** (deterministic per-conversation order that doesn't rely on client clocks) and a correct **idempotency / no-duplicate-send strategy**.
- A correct, well-reasoned **Redis vs Kafka** split, including why a fire-and-forget pub/sub layer can't be the store of record and why Kafka is not the simplest online-delivery path here.
- A credible explanation of **Kafka fundamentals** (topics, partitions, offsets, replication, retention/replay) and its tradeoffs.
- **Scaling** (stateless WebSocket servers, connection routing in a shared store, sharding by conversation/user) and **failure handling** (crash between persist and deliver, retries, stale presence).
### Follow-up Questions
- The recipient is online and the message is persisted, but the WebSocket server holding their connection crashes before delivery. How does the message still reach them, and how do you avoid losing or duplicating it?
- How would you route a send when the sender and recipient are connected to **different** WebSocket servers? What does the connection-routing layer look like?
- Now relax the single-device assumption: how do presence, unread counts, and read receipts change with **multiple devices** per user?
- A user has been offline for a week and reconnects. How does the client efficiently fetch exactly the messages it missed, in order, without re-downloading everything?
Quick Answer: This question evaluates a candidate's ability to design scalable, real-time one-to-one messaging systems, testing competencies in transport choice for server→client push, presence detection, durable message storage and delivery semantics, ordering, idempotency, and technology trade-offs between short-lived online state and durable pipelines.