Walkthrough: News Feed
The intuition: mail carrier or newsstand
Think about newspapers. One way to get them out is a mail carrier: as soon as an issue is printed, it goes into every subscriber's mailbox. In the morning you open the box and everything is already there. That's push, or fan-out on write. The other way is the newsstand: you walk up, and the vendor pulls together the latest issues of everything you subscribe to. That's pull, or fan-out on read.
The mail carrier works great while a paper has a thousand subscribers. With 50 million subscribers, there's no way to deliver the issue in time. That difference is what this whole case is about.
Numbers first
In an interview, estimate the scale right away. Without it, you can't justify picking push or pull.
| Parameter | Estimate |
|---|---|
| DAU | 300M |
| New posts per day | 100M → ~1,200 posts/s |
| Average follower graph | 200 followers per author |
| Feed writes with push | 1,200 × 200 ≈ 240K inserts/s |
| Feed opens | 300M × 10 per day ≈ 35K reads/s |
| A celebrity post (50M followers) | 50M inserts for a single post |
There are a lot of feed reads, and the user expects a response in ~100–200 ms. So you want to serve the feed precomputed. But celebrities make push explode.
Fan-out on write (push)
The post is saved, and an event goes into a queue. Workers fetch the follower list from the follow graph and append the post_id to each follower's feed in Redis. On read, the feed service takes the ready-made list of ids and pulls in the post contents.
- Pros: fast reads, simple serving.
- Cons: expensive writes. For celebrities, catastrophically expensive. Feeds of inactive users get updated too, which is wasted work.
Fan-out on read (pull)
Nothing is laid out ahead of time. When you open your feed, the service fetches the list of people you follow, grabs each author's latest posts, and merges them by time (merge K sorted lists).
- Pros: a write costs O(1), no wasted work, celebrities aren't a problem.
- Cons: reads are heavy. If you follow 500 accounts, that's 500 lookups plus a merge, for each of 35K requests per second. Latency goes up.
Hybrid: what people actually do
Set a threshold on follower count, say 10K:
- Regular authors go through push: their posts are laid out into feeds ahead of time.
- Celebrities go through pull: their posts live only in the "author's latest posts" cache.
- On read, take the precomputed feed from Redis, add fresh posts from the celebrities you follow (usually just a handful), merge, and return.
Tip: say out loud "push for most people, pull for celebrities, merge on read." The interviewer is almost always waiting for exactly that sentence, followed by a question about the threshold.
Inactive users belong here too. If someone hasn't logged in for a month, don't fan out to their feed; build it with pull when they come back.
Storing the feed in a cache
- In Redis, store only post ids, not the content:
feed:{user_id}→ a list of the ~800 latestpost_ids. - Size: 8 bytes × 800 ≈ 6.4 KB per user. For 300M users that's ~2 TB of raw data, and noticeably more with Redis overhead. So keep feeds only for active users and shard by
user_id. - Fetch text, likes, and authors separately (hydration) from the post cache. That way editing a post doesn't mean rewriting millions of feeds.
Cursor pagination
offset pagination breaks here. While you scroll, new posts appear at the top, everything shifts, and you see duplicates. Instead, pass a cursor: the last post_id you saw, or a "timestamp + id" pair.
GET /v1/feed?limit=20&cursor=eyJsYXN0X2lkIjoxODQ0Njc0fQ
→ 200 { "items": [...], "next_cursor": "eyJsYXN0X2lkIjoxODQ0NjU0fQ" }A cursor stays stable when posts are inserted at the top, and "give me 20 posts older than X" is a cheap query.
Ranking in brief
Chronological order is the baseline. A ranked feed works in two stages. First you gather candidates: the same push and pull, a few hundred posts. Then you score them with a model using features like closeness to the author, engagement, freshness, and content type. Scoring can happen at read time. The alternative is to recompute feeds offline periodically. The trade-off: the smarter the model, the more expensive each read.
Common mistakes
- Picking push and forgetting about celebrities.
- Storing full posts in the feed instead of ids.
- Paginating with
offset. - Not mentioning a queue: a synchronous fan-out inside the publish request blocks the author.
- Building feeds for every user, including the "dead" ones.
Your turn
The interviewer asks: "Okay, a hybrid. But what happens if a regular author suddenly gains 2 million followers in a day? And how would you handle deleting a post that's already been fanned out into feeds?"
Answer it yourself. Think through three things:
- How and when an author switches between push and pull.
- What happens to the already fanned-out ids when a post is deleted: clean up the feeds, or filter during hydration.
- What level of consistency you're willing to accept here.