11 system design interview questions on chat, news feeds and notifications, each with the correct answer and a full explanation.
Messages in a conversation must appear in the same order on every device. What provides that order?
Show answer
Answer
A per conversation sequence number assigned where the conversation is owned
One owner per conversation (its partition or leader) can assign a monotonically increasing sequence, and clients sort by it. Client clocks skew and can be set to anything. Wall clocks on different servers also drift. A global sequence is a needless bottleneck when ordering only matters within a conversation.
A phone was offline for 2 hours. On reconnect, how does it get exactly the messages it missed?
Show answer
Answer
It sends its last seen sequence per conversation and the server returns everything after
A sync cursor makes catch up cheap and exact. Resending everything wastes bandwidth. Push delivery is best effort and coalesced, not a reliable transport. Client clocks are skewed, so a time based query misses or repeats messages.
You show online status. Clients can vanish without disconnecting (dead battery, tunnel). How do you detect offline?
Show answer
Answer
Clients heartbeat every few seconds and are marked offline when the heartbeat TTL expires
Heartbeats with a TTL (for example in Redis) catch silent disappearances within seconds. Users rarely log out. Last login says nothing about now. Default TCP keepalive waits around 2 hours before probing.
A feed service: average user has 200 followers, a few accounts have 50 million, reads far outnumber writes. Which fanout?
Show answer
Answer
Hybrid: push to followers' timelines for normal users, pull celebrity posts at read time
Push makes reads cheap for the common case; pulling the few celebrity accounts at read avoids 50 million writes per post, which is Twitter's approach. Pure push melts on celebrity posts. Pure pull makes every read merge hundreds of sources. A global timeline filtered per user does not scale.
Precomputed timelines live in Redis. Why store only post IDs (capped at a few hundred per user) instead of full post bodies?
Show answer
Answer
IDs keep memory small and edits or deletes apply once in the post store
Copying bodies into millions of timelines multiplies memory and makes every edit or delete a fanout. IDs are hydrated from a post cache. Redis strings can be up to 512 MB. Consistency does not come from storing bodies. You still need a post cache to hydrate the IDs.
Your iOS app is closed. How does your backend notify the user about a new message?
Show answer
Answer
Send a push through APNs using the device token
Only Apple's push service can wake or alert a closed app; your server sends to APNs with the device token (FCM on Android). iOS suspends background sockets. SMS costs money and is a different channel. A closed app cannot poll.
A webhook platform: one merchant's endpoint returns 500 for every request, and retries are delaying delivery to all other merchants. What fixes it?
Show answer
Answer
Per destination queues or rate limits with backoff, and a dead letter queue after N attempts
Isolating by destination stops one bad endpoint from blocking the rest, and backoff plus DLQ bound the work spent on it. A shared retry queue keeps the head of line blocking. Tight retry loops burn workers. Dropping after one failure breaks at least once delivery for transient errors.
Customers register webhook URLs that your servers call. An attacker registers a hostname that resolves to 169.254.169.254. What protects you?
Show answer
Answer
Resolve and check the IP at send time against private and metadata ranges, through an isolated egress proxy
SSRF is blocked by validating the resolved address on every request (DNS can change after registration) and sending from a network that cannot reach internal services. https does not limit the destination. A registration time check is defeated by DNS rebinding. POST requests to internal endpoints can still do damage.