Skip to content
HLD Learn/Capstone Case Studies

Worked Example: Designing a News Feed (like Twitter/Instagram)

8 min read

You'll learn to

  • -Apply the design loop to the classic fan-out trade-off
  • -Understand the celebrity problem and why real systems use a hybrid push/pull design

This is widely considered one of the hardest "classic" system design questions, and for good reason: the naive solution to feed generation has a scaling flaw that only shows up once you run the numbers, which is exactly why Step 2 matters so much in this one.

Step 1: Clarify Requirements

  • -Functional: users follow other users; a user's home feed shows recent posts from everyone they follow, most-recent first.
  • -Out of scope: ranking/ML-based ordering (assume simple reverse-chronological for this design, worth stating explicitly, since real systems rank feeds, but that's a separate, much larger problem).
  • -Non-functional: opening the app and loading the feed must feel instant (well under 200ms), far more important than write latency, since a slow post is annoying but a slow feed feels broken every single time the app opens.

Step 2: Estimate Scale - and Find the Trap

Assume 200 million daily active users, each posting an average of 2 times per day, and following an average of 200 other accounts.

The Fan-Out Multiplier
~4,600/sec
Average posts created/sec (200M × 2 ÷ 86,400s)
~925K/sec
Feed-cache writes/sec IF every post fans out to all ~200 followers
50M+
Followers a single celebrity account can have
~200x
Write amplification from a naive "push to everyone" design

That 200x multiplier is the entire crux of this problem. A single post from an average user costs ~200 feed-writes. A single post from a celebrity with 50 million followers costs 50 million feed-writes, all for one post. Any design that treats every user the same will fall over the first time a celebrity tweets.

Step 3: High-Level Design - Two Competing Strategies

1Fan-out-on-write (push): precompute every follower's feed
Poster
Post Service
Message Queue
Fan-out Worker
Follower A Feed

Reads are extremely fast (just fetch the precomputed list), but a celebrity post triggers millions of writes at once.

PosterPost Service- new postPost ServiceMessage Queue- fan-out jobFan-out WorkerFollower A Feed- push post ID to every follower's feed list
2Fan-out-on-read (pull): merge at feed-load time
Reader
Feed Service
Posts (by author)

No write amplification at all, but loading a feed now means fetching and merging from every followed account, live.

ReaderFeed Service- GET /feedFeed ServicePosts (by author)- fetch + merge posts from all ~200 followed accounts

Step 4: Deep Dive - The Hybrid Solution

Neither strategy alone works at scale: pure push is destroyed by celebrities; pure pull makes every single feed load expensive for everyone, including users who never encounter a celebrity post. Real systems (this is the answer Twitter and Instagram actually ship) use a hybrid:

  • -For accounts under a follower threshold (say, 100K): fan-out-on-write as normal. This covers the overwhelming majority of accounts, and keeps their followers' feed reads fast.
  • -For accounts over that threshold (celebrities): skip fan-out entirely. Their posts are NOT pushed to any feed cache.
  • -At feed-load time, a user's precomputed (pushed) feed is merged with a live, on-the-fly fetch of recent posts from any celebrities they follow, a small, bounded number of extra lookups, since one person only follows so many celebrities.

This is the single most important insight in this whole design: the fan-out strategy is not a single global choice: it is a per-account decision, made based on follower count, and that is what makes the system scale in both directions at once.

Step 5: Trade-offs & Failure Modes

  • -Consistency: it is entirely acceptable for a new post to take a few seconds to appear across all of a regular user's followers' feeds; the fan-out worker queue absorbs the write burst asynchronously (Module 8), and nobody expects instant global feed propagation.
  • -Storage cost: precomputing feeds means storing the same post ID redundantly across every follower's feed cache, a deliberate trade of extra storage for much faster reads, the same trade-off named back in the Caching module.
  • -Failure mode: the fan-out queue backs up during a traffic spike (a viral moment). Posts still get created and stored immediately; only the fan-out to followers' feed caches lags. Feeds get briefly stale rather than the system failing outright, a graceful degradation, not an outage.
Interview Signal

"Just fan out every post to every follower's feed on write: it's simple and reads are fast." What's the problem with stopping there?

Weak Answer

"That sounds reasonable, most users don't have that many followers anyway."

Strong Answer

"Most don't, but the ones with 50 million followers turn one post into 50 million writes, all at once, and that has to go somewhere: a queue that can't drain in time, or a database that falls over. Making fan-out-on-write conditional fixes it: below a follower-count threshold, push; above it, pull at read time and merge. The threshold is what keeps the system's worst case bounded instead of unbounded."

Check Yourself1 / 3

What is the "celebrity problem" in feed design?

Ready to Build This?

Level 10: News Feed System in the HLD Lab is exactly this system - go build the design you just walked through.

ScaleDojo Logo
Initializing ScaleDojo