Dev Skills

Follower timeline

Design the home timeline for a social product. People follow each other; when you open the app you see recent posts from everyone you follow, newest first. Some accounts have tens of millions of followers.

Where’s the slack?

Reads: ~200 ms. Post visibility: seconds. Counts: minutes.

A reader cannot tell when a post was supposed to appear in their feed. So you have seconds of slack on delivery, and almost none on opening the app.

This is the key asymmetry. Opening the app has a hard budget: the timeline must render in a couple of hundred milliseconds or the product feels broken. But readers do not time when someone else's post shows up. If it appears two seconds after it was posted, or ten, the reader cannot tell, because they have no reference clock.

That slack is what makes fan-out on write possible. You can do a large amount of work asynchronously between "they posted" and "it appears in feeds", because readers are not watching that interval. The exception is the author, who knows when they posted and will often refresh at once. Their view of their own post has zero slack and needs a different path.

Counts (likes, replies, views) have minutes of slack. A reader cannot tell 4,102 from 4,118. That is what lets you batch and approximate them instead of writing to a contended row on every interaction.

So: Seconds of delivery slack means you can precompute timelines in the background rather than assembling them on read. Zero slack on the author's own view means you special-case it. Minutes of slack on counts means they never go near the hot path.

Work it through

Five stages, gated. You write your answer for each stage before its model answer unlocks. That is the core of the method.

Loading your progress…

Reference material for this problem. The diagrams below are here to check your own against once you have drawn it, not to read first.

The lifecycle

ComposedauthorStoredsystemQueuedoutbox relayIn inboxesfan-out workersReadfollowersFan-out event lostoutbox in the same transaction, so it cannot be lostAuthor has 30M followersabove threshold, skip fan-out entirely; readers pullWorker dies mid-jobretry; inbox writes idempotent on post idQueue backed uptimelines silently stale; alert on message age, not depthPost deletedtombstone, filter at hydration, clean inboxes lazily
A post's life. Every branch below is a real production failure mode. The fan-out job dying partway through is the one candidates tend to forget.

The numbers

Posts created~1,000 / sec
Timeline opens~20,000 / sec
Inbox writes (fan-out at 300 followers)~300,000 / sec
One post from a 30M-follower account30,000,000 writes

So the hard part is fan-out amplification, and specifically its tail. The average says 300x; the worst case says 30 million, and the worst case is what takes the system down.

The multiplication that is easy to forget. The post rate is not the workload.

The architecture

one txnrelaypush pathpull pathAuthorPost svcPosts + outboxFan-out queueFan-out workersidempotentInboxesby user id, cappedReaderTimeline svcmerge + hydrateBig-account cacherecent posts
Two paths that meet at the timeline service. Ordinary accounts are pushed into inboxes; huge accounts are pulled at read time and cached hard.

The mechanism

Authorposts onceFan-outInbox 1Inbox 2Inbox 3
one write inmany writes out — reads later are free
One write in, many writes out. Expensive writes buy cheap reads, until one author has 30 million followers.

The decision this turns on

A
Fan-out on write (push)
  • —Reads are one sequential lookup of a precomputed list. Fast and cheap.
  • —Write cost is multiplied by the follower count.
  • —A huge account turns one post into millions of writes and blocks the queue.
  • —Storage grows with posts times followers, not with posts alone.
B
Fan-out on read (pull)
  • —Writes are trivial: store the post once and stop.
  • —Reads query every account you follow and merge, which is hundreds of lookups.
  • —Perfect for huge accounts: their posts are read by millions, so cache hit rates are near 100%.
  • —Hopeless at 20,000 timeline opens a second for ordinary users.
Which one: Push for ordinary accounts, pull for the few above a follower threshold, and merge the two at read time. The threshold is the main design decision, and it should be tuned by watching fan-out queue age rather than picked as a round number.
Push versus pull. The reason the answer is "both" is the follower distribution.

Follow-ups you should expect

Many interviews are decided in the follow-ups, not the first diagram.

Same shape, other products

One action by one person creates work for thousands of other people.

The question is always the same: do you do that work when they write, or when everyone else reads? And what do you do about the one user with 200 million followers?

Others with this shape: Twitter timeline · Chat delivery · Notification system · Activity feed

Before you leave
Try this problem again in a week without reading anything. Comparing what you write then with what you wrote today shows you what stuck.
Stuck, or new to this?Read the full worked solutionAll five stages end to end, with the diagrams and the costs, written out the way you would say it. Best read after you have had a go.Read it →

How it is really built

Write your own answer first. Then read how teams who run this at scale describe it. Their constraints were real, and the write-ups often say what their choices cost.