Design a news feed
Balance fan-out on write and fan-out on read for a social timeline.
- Compare fan-out on write with fan-out on read.
- Handle celebrity accounts with a hybrid approach.
- Paginate a feed with cursors and store media efficiently.
Requirements. Users publish posts, follow other users, and view a home feed of posts from people they follow, newest first. Non-functional: loading the feed must be fast (it is the most frequent request), availability matters more than perfect freshness, and a few seconds of delay before a post appears is acceptable. That tolerance is a hint: the feed can be eventually consistent.
Push, pull, or both
- Fan-out on write (push): when someone posts, write the post id into a precomputed feed for each follower (for example a Redis sorted set per user). Reading a feed is one fast lookup, but posting costs one write per follower.
- Fan-out on read (pull): at read time, fetch recent posts from everyone the user follows and merge them. Posting is cheap; reading is slow and expensive.
- Hybrid: push for normal accounts; for celebrities with millions of followers, skip fan-out and merge their recent posts in at read time.
followers = {"ada": ["bo", "cy"], "celebrity": [f"fan{i}" for i in range(1_000_000)]}
for author, fans in followers.items():
print(f"{author}: {len(fans):,} feed writes per post")ada: 2 feed writes per post celebrity: 1,000,000 feed writes per post
The feed cache stores post ids, not whole posts; the feed service then hydrates ids from a post cache, so an edited post is fixed in one place. Fan-out runs asynchronously through a queue. Paginate with a cursor (“posts older than id X”) instead of an offset, so new posts do not shift pages and cause duplicates. Images and videos go to object storage served through a CDN, and posts store only their URLs. Ranking by relevance is a common extension.
Key takeaways
Push makes reads cheap; pull makes writes cheap; the hybrid handles celebrities.
Cache post ids per feed and hydrate them from a post cache.
Use cursor pagination and serve media from object storage through a CDN.
Lesson quiz
6 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: simulate system design building blocks
Use small Python programs to estimate capacity and simulate caches, load balancers, hash rings, and rate limiters. These exercises run locally in your browser.
Merge followee timelines
Read k, then a count m, then m timelines. Each timeline is a line of timestamp:post_id items, newest first. Print the k newest post ids across all timelines, newest first, separated by spaces. Timestamps are unique.
- Three timelines
- Two timelines
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…