System Design Ch.9: News Feed for 20 Million Followers
Outline
- 0:00 Twenty Million Followers. One Tap.
- 0:12 The News Feed Map.
- 0:42 One Author. One Tap.
- 0:57 Two Equally Bad Answers.
- 1:20 Functional Requirements.
- 2:03 Non-Functional Requirements.
- 2:52 Fan-Out on Read.
- 3:23 Fan-Out on Write.
- 3:54 The Celebrity Ceiling.
- 4:29 Hybrid Serving.
- 5:09 Ranking Changes the Design.
- 5:57 Deduplication and Social Context.
- 6:29 Post-Ranking Rules.
- 7:12 The Map, Revisited.
- 7:53 The Final Tradeoff.
Transcript
0:00 Welcome to Learning Podcasts. System Design, chapter nine: News Feed. Today we design a news feed that actually survives one famous author posting to twenty million followers. Before we go anywhere, look at this map. We have a post store on one side, a social graph that knows who follows whom, fan-out workers, precomputed home timelines, a feed retrieval service, a ranker, a policy and dedup layer, hydration, the feed API, and a small realtime channel on the side. That is a lot of boxes for what feels like a list of posts.
0:35 We are going to earn each one. By the end, every box will be a tradeoff we walked through. One author taps publish. A breaking-news post leaves the device. A few hundred bytes of text, a media pointer, a timestamp. That part is easy. One write, one row. That part is easy. The hard part is what happens next. Now you have two equally bad answers. Door one, write that post into twenty million home feeds right now. Door two, wait until each follower opens the app and assemble the feed then. Door one is a storm of writes. Door two is a storm of reads.
1:13 Both answers break the system. That is the trap. The hard part is not storing posts. The hard part is the read model. Let us pin down the functional requirements first. The system must let users create posts and store them durably. It must maintain the social graph: follows, blocks, mutes, groups. It must generate a home feed for a viewer, page through older items, and refresh when new ones arrive. Standard feed surface so far. It must also support engagement signals: likes, comments, replies, reshares, hides.
1:47 It must hide content the viewer is not allowed to see, collapse duplicate appearances of the same story, and explain why each item is in the feed. Explanations matter. Why is this in my feed. That answer has to come out of the system, not be retrofitted later. Non-functional requirements next. Read latency must be low because opening the app and scrolling are the entire user experience. Freshness matters, but not every item needs to land globally in the same second. Availability beats perfect ordering.
2:19 Privacy and block rules are non-negotiable, even on a stale feed. So the cache cannot be the source of truth on what someone is allowed to see. Write amplification has to be bounded because a high-follower author can turn one post into millions of operations. Ranking cost has to be controlled because algorithmic feeds retrieve more candidates than they show. Hot authors have to be isolated so they do not starve normal authors. And we need real observability into all of this. Otherwise we are flying blind.
2:51 The simplest read-time design is fan-out on read. When a viewer opens the feed, fetch the accounts they follow, fetch recent posts from each author, merge, filter, rank, return the top page. Publishing is just one durable write to the author's timeline. Nothing is copied to followers at publish time. Cheap write, expensive read. Right. If the viewer follows a thousand accounts, the feed request touches many timelines and pulls back far more posts than it shows. Fine when the follow set is small. Painful when it is large.
3:21 Flip it. Fan-out on write. When an author publishes, the system fetches the followers and writes the post ID into each follower's precomputed home timeline. Opening the feed becomes reading a ready-made list, hydrating the post IDs, applying late filters, returning the page. The same pattern as the queue we used in chapter four, just with a much bigger blast radius. Yes. And it is powerful because reads outnumber writes by a wide margin. Most users open and scroll far more often than they publish.
3:53 But fan-out on write has a ceiling. A normal author with five hundred followers creates five hundred downstream insertions. Fine. A public account with twenty million followers creates twenty million insertions per post. That is not more of the same work. It saturates fan-out workers, floods timeline stores, and delays ordinary posts behind famous posts. One celebrity throttles every other author. And we are paying storage on precomputed feeds for users who may not open the app for months. So the practical answer is hybrid.
4:31 Fan-out on write for ordinary authors whose follower count is small enough to precompute cheaply. Fan-out on read for very-large authors and for inactive viewers whose feeds are not worth keeping warm. When a viewer opens, the retrieval service combines the precomputed home timeline with pulled candidates from the big-author path, then ranks and filters the merged set. Same idea as the room-level fan-out we ended chapter seven with. Same idea, different surface. The threshold between push and pull is not moral.
4:58 It is an engineering knob shaped by follower distribution, read frequency, freshness goals, and ranking cost. The product feels like one feed. The backend has several serving paths. Ranking changes the design again. A chronological feed can store post IDs in reverse time order and be done. An algorithmic feed needs candidate generation, scoring, and final serving as three distinct steps. Candidate generation asks, what could this viewer plausibly see. Ranking asks, which of those are most valuable to show now.
5:32 Final serving asks, which items are allowed, non-duplicate, and stable enough to put on this page. So the feed store cannot just be the final list forever. It has to preserve enough candidate inventory that ranking can choose at request time. And ranking changes how much inventory you retrieve, where features must live, and how you debug why one item appeared above another. Deduplication is where feeds get subtle. The same post can arrive through several paths. You follow the author. Someone you follow reshared it.
6:05 A friend commented. A group surfaced it. A recommendation source picked it. Five paths, one underlying post. Showing it five times is a bad feed. Right. The system needs a canonical content ID and a way to merge reasons. The displayed item is one card with stacked context: Iva and two others commented. Diversity is related but different. If the top twenty scores all belong to one author or one content type, a pure score sort feels repetitive. Many feeds apply diversity, fatigue, and negative-feedback rules after initial scoring.
6:44 Privacy and eligibility get checked twice: early at candidate generation, and late at serving, the same way notification policy gates work in chapter eight. Because cached eligibility goes stale. Realtime updates need restraint. Tell the client new posts are available and let the user refresh. Pagination needs a session cursor, not a fresh sort, or page two reshuffles. Observability has to split: write side for fan-out lag, read side for feed latency and ranker time. Now back to the map. The post store holds the canonical post.
7:16 The social graph defines who can see what. Fan-out workers precompute home-feed entries for ordinary authors and active viewers. Very-large authors, recommendations, and groups get pulled at read time. The feed retrieval service gathers candidates from all of those. The ranker scores them. The policy layer enforces visibility. Deduplication merges duplicate stories. Diversity rules shape the page. Hydration fetches the final post data. The feed API returns a stable cursor to the client. The realtime channel announces new items without forcing the page to reorganize under the user.
7:53 Every box was a tradeoff. Precompute enough that the hot read path is fast. Not so much that one famous author or millions of inactive viewers dominate the write path. Pull enough at read time that ranking and freshness stay intelligent. Not so much that every scroll becomes a query across the whole social graph. A good news feed is a controlled negotiation between write amplification, read latency, freshness, ranking quality, and user trust. Next chapter we go from a whole feed to the first few characters in a search box.
8:27 Thanks for listening to Learning Podcasts.