Design a News Feed (Facebook / Twitter) — System Design
Design a social news feed end to end: the fan-out problem (push vs pull), the celebrity fan-out storm, the hybrid solution, async fan-out workers, feed caching, and modern ranking.
🟠 High-Level Design · Senior → 🔴 the fan-out deep dive
"Design the news feed for Facebook / Twitter / Instagram." This one is a rite of passage, because it hides a genuinely hard trade-off called fan-out — and how you handle the "celebrity with 100 million followers" problem separates a memorised answer from real understanding. Let's design a feed from scratch and go deep exactly where the interview does.
Step 1 — Requirements
- Functional: a user can post; a user follows others; a user sees a feed of recent posts from people they follow, newest/ranked first; feed loads fast and paginates as you scroll.
- Non-functional: extremely read-heavy (people scroll far more than they post), low latency on feed load (it's the app's front door), and highly available. Eventual consistency is fine — a post appearing a few seconds late is acceptable.
Step 2 — The two core operations
🟠 A feed system is really two flows: write path (someone creates a post) and read path (someone loads their feed). The entire design hinges on how you connect them — and that's the fan-out decision.
Step 3 — Fan-out on read (pull)
The simplest model: store each post once. When a user opens the app, pull — fetch the recent posts of everyone they follow, merge, sort, and return.
- Pro: writing a post is cheap (one insert); no wasted work; great if users rarely check their feed.
- Con: reading is expensive and slow. If you follow 500 people, every feed load queries 500 users' posts and merges them — on the hot path, at scale, that's brutal. Reads happen constantly, so making them expensive is the wrong trade.
Step 4 — Fan-out on write (push)
🟠 Flip it: do the work when someone posts. Each user has a precomputed feed (a cache/list of post IDs). When Alice posts, you push that post ID into the feed of every one of her followers immediately. Reading is then trivial — just return the user's ready-made feed.
- Pro: reads are lightning fast — the feed is already built. Perfect for a read-heavy system.
- Con: writing is expensive and, for popular accounts, catastrophic — a celebrity with 100M followers means one post triggers 100 million writes (the "fan-out storm"). And you precompute feeds for inactive users who may never look.
Step 5 — The winning answer: a hybrid
🔴 Neither pure model works at scale, so real systems (this is roughly how Twitter/Instagram do it) combine them:
- For normal users: use push (fan-out on write). Pre-build followers' feeds so reads are instant. Most accounts have modest follower counts, so the write cost is fine.
- For celebrities / huge accounts: use pull. Don't fan-out their posts to 100M feeds. Instead, when a follower loads their feed, take their pre-built feed (from the people they push-follow) and merge in the latest posts of the few celebrities they follow at read time.
So a feed load = "my precomputed feed" + "a quick pull of the handful of mega-accounts I follow," merged and ranked. This kills the fan-out storm while keeping normal reads instant. Naming this hybrid and why (the celebrity problem) is the whole point of the question.
Step 6 — Architecture & data
The write path uses a message queue: posting drops an event, and fan-out workers asynchronously push the post ID into follower feeds — so the user's "post" click returns instantly while distribution happens in the background. Feeds live in a fast store (Redis lists of post IDs); post content and the social graph live in databases.
posts: post_id, author_id, content, created_at follows: follower_id, followee_id (the social graph) feed cache (Redis): user_id → [post_id, post_id, …] (precomputed)
Feeds store IDs, not full posts — you hydrate the actual content from cache/DB when rendering, so a post edit or delete is reflected everywhere without rewriting millions of feeds.
Step 7 — Ranking (the modern twist)
🔴 Modern feeds aren't purely chronological — they're ranked by relevance (engagement signals, recency, affinity). Architecturally, you still fan-out candidate post IDs, then a ranking service scores and orders them at read time. Mentioning "candidate generation via fan-out, then a ranking layer" shows you know today's feeds, not just 2010's timeline.
The interview-ready walkthrough
"A feed is read-heavy, so I'd optimise reads with fan-out on write — precompute each user's feed as a Redis list of post IDs via async fan-out workers behind a queue. But pure push breaks for celebrities (a post would trigger 100M writes), so I'd go hybrid: push for normal users, and for mega-accounts pull their latest posts at read time and merge them into the follower's feed. Feeds store IDs (hydrate content separately), and a ranking layer orders candidates by relevance. That gives instant reads without the fan-out storm." That is exactly the arc interviewers are hunting for."
What to read next
- Design a Chat System — real-time delivery, the next level up
- Message Queues & Kafka — the async fan-out backbone
- Caching Strategies — where precomputed feeds live
- ← The complete System Design guide (hub)