AI InterviewSearch…Search problems, topics, or pages…Ctrl KGet started
Skip to content
SD notes

System Design · Note 17 of 22

Design a News Feed

Intermediate · 7 min read · updated 14 November 2026

Quick answer

How do you design a news feed system?

Store posts once, then build each user's feed either at post time (fan-out on write: push the post id into every follower's cached feed) or at read time (fan-out on read: pull and merge followed accounts' posts). Large systems mix both: push for ordinary accounts, pull for celebrities, merge at read time, and page the result with cursors.

On this page
  1. Requirements
  2. Capacity estimate
  3. API
  4. Data model
  5. Fan-out on write (push)
  6. Fan-out on read (pull)
  7. The hybrid for celebrities
  8. Ranking and pagination
  9. Bottlenecks and trade-offs
  10. Interview questions
  11. Common questions

A news feed is the list of recent posts from the accounts you follow. The design problem is when to do the work of building it: when someone posts, or when someone reads.

Requirements

  • Functional: post text/media; follow accounts; see a feed of followed accounts' posts, newest or ranked first; scroll for more.
  • Non-functional: the feed loads fast (aim for a few hundred ms); a post may take seconds to appear (eventual consistency is fine); highly available.
  • Read-heavy: feeds are read far more often than posts are written.

Capacity estimate

Assumptions: 200 million daily users, each opens the feed 10 times and posts 0.5 times a day, 200 followers on average.

QuantityWorkingResult
Feed reads / s200 M × 10 ÷ 86,400≈ 23,000
Posts / s200 M × 0.5 ÷ 86,400≈ 1,157
Fan-out writes / s1,157 × 200≈ 231,000
Feed cache200 M × 500 ids × 8 B800 GB
  • Fan-out multiplies writes by the follower count; that number drives the whole design.

API

HTTP
Copy
POST /v1/posts                       {"text": "..."}  → 201 {"id": "p9"}
GET  /v1/feed?limit=20               → {"posts": [...], "nextCursor": "p18"}
GET  /v1/feed?limit=20&cursor=p18    → the next page, older than p18

Data model

StoreKeyHolds
postspostIdauthorId, body, createdAt
follows(followerId, followeeId)both directions indexed
feed cacheuserIdnewest ~500 post ids
post cachepostIdhydrated post for display

Fan-out on write (push)

  • At post time, a worker copies the post id into each follower's feed cache.
  • Read = one cache read. Cost = one write per follower.
Fan-out on write: push the post into every follower's feed

Asha publishes p9. With fan-out on write, the work of building feeds happens now, at post time.

0:01 / 0:14Step 1 of 6
Transcript · 6 steps

Fan-out on read (pull)

  • At read time, fetch each followee's recent posts and merge.
  • Posting is free; reading is slow for users following thousands.
Fan-out on read: pull from everyone you follow, then merge

Nothing was precomputed. When Ben opens his feed, the feed service reads who he follows: Asha, Chen, Dev.

0:01 / 0:12Step 1 of 5
Transcript · 5 steps
Push (on write)Pull (on read)
Read latencyLowHigh
Write cost× followersOne write
Celebrity postMillions of writesCheap
Inactive usersWasted writesNothing wasted

The hybrid for celebrities

  • Push for ordinary accounts; above a follower threshold, store once and pull.
  • The reader's feed = cached ids + a few celebrity pulls, merged.
Hybrid fan-out: push for most accounts, pull for celebrities

The hybrid: fan out on write for ordinary accounts, but not for celebrities, whose posts would cost millions of writes each.

0:01 / 0:14Step 1 of 5
Transcript · 5 steps

Ranking and pagination

  • Ranking: take a few hundred candidates, score them (recency, affinity, engagement), return the top. Plain time order is the baseline.
  • Cursor pagination: "older than the last post I saw", never OFFSET.
Cursor pagination: no repeats when new posts arrive

Page 1 returns the newest 3 posts, p20, p19, p18, and a cursor naming the last one shown, p18.

0:01 / 0:11Step 1 of 4
Transcript · 4 steps

Bottlenecks and trade-offs

  • Fan-out lag: a queue absorbs bursts; posts appear after seconds, not instantly.
  • Hot feed caches: shard by user id with consistent hashing.
  • Posts table: shard by author; cache hot posts.
  • Deletes and unfollows leave stale ids in caches; filter at read time.

Interview questions

  • Push or pull? Push for most users, pull for celebrities: the hybrid.
  • What goes in the feed cache? Post ids, not bodies, so an edit changes one record.
  • Why cursors? Offsets repeat or skip posts as new ones arrive.
  • How do you rank? Score a candidate set by recency and engagement; time order is the fallback.

Next: Design a Notification System · Before this: Design a Chat App (WhatsApp)

Common questions

What is fan-out on write?

When someone posts, a worker pushes the post's id into the cached feed of every follower. Reading a feed is then a single fast cache read, but one post costs one write per follower, which is expensive for accounts with millions of followers.

What is fan-out on read?

Nothing is precomputed. When a user opens the feed, the service fetches the recent posts of everyone they follow and merges them by time or rank. Posting is cheap, but every feed load does many queries, which is slow for users who follow thousands of accounts.

How do you handle celebrities with millions of followers?

Use the hybrid model. Accounts above a follower threshold are not fanned out; their posts are stored once and pulled at read time, then merged with the reader's precomputed feed. Writes stay bounded and each read adds only a few lookups.

Why use cursor pagination for a feed instead of offset?

New posts keep arriving at the top, so an offset shifts under the reader and repeats or skips posts. A cursor says continue after the last post I saw, which stays correct as the list changes and uses an index seek instead of skipping rows.

Where are feeds stored?

Usually as short lists of post ids in an in-memory store such as Redis, a few hundred per user, with post bodies fetched separately from a post cache or database. Inactive users' feeds can be dropped and rebuilt on their next visit.

Design a News Feed: Fan-out on Write vs Read

Design a news feed like Twitter or Instagram: fan-out on write vs read, the hybrid for celebrity accounts, feed caches and cursor pagination, each animated.

  • Subject: System Design
  • Level: Intermediate
  • Reading time: 7 min
  • Updated: 2026-11-14

How do you design a news feed system?

Store posts once, then build each user's feed either at post time (fan-out on write: push the post id into every follower's cached feed) or at read time (fan-out on read: pull and merge followed accounts' posts). Large systems mix both: push for ordinary accounts, pull for celebrities, merge at read time, and page the result with cursors.

A news feed is the list of recent posts from the accounts you follow. The design problem is when to do the work of building it: when someone posts, or when someone reads.

Requirements

  • Functional: post text/media; follow accounts; see a feed of followed accounts' posts, newest or ranked first; scroll for more.
  • Non-functional: the feed loads fast (aim for a few hundred ms); a post may take seconds to appear (eventual consistency is fine); highly available.
  • Read-heavy: feeds are read far more often than posts are written.

Capacity estimate

Assumptions: 200 million daily users, each opens the feed 10 times and posts 0.5 times a day, 200 followers on average.

QuantityWorkingResult
Feed reads / s200 M × 10 ÷ 86,400≈ 23,000
Posts / s200 M × 0.5 ÷ 86,400≈ 1,157
Fan-out writes / s1,157 × 200≈ 231,000
Feed cache200 M × 500 ids × 8 B800 GB
  • Fan-out multiplies writes by the follower count; that number drives the whole design.

API

POST /v1/posts                       {"text": "..."}  → 201 {"id": "p9"}
GET  /v1/feed?limit=20               → {"posts": [...], "nextCursor": "p18"}
GET  /v1/feed?limit=20&cursor=p18    → the next page, older than p18

Data model

StoreKeyHolds
postspostIdauthorId, body, createdAt
follows(followerId, followeeId)both directions indexed
feed cacheuserIdnewest ~500 post ids
post cachepostIdhydrated post for display

Fan-out on write (push)

  • At post time, a worker copies the post id into each follower's feed cache.
  • Read = one cache read. Cost = one write per follower.
Asha postsFan-out workerwrites: 4Benp9p7p5Chenp9p6Devp9p7p4Elip9feed caches, newest first
Fan-out on write: push the post into every follower's feed.
  1. Asha publishes p9. With fan-out on write, the work of building feeds happens now, at post time.
  2. A fan-out worker takes the post from a queue and reads Asha's follower list: 4 followers.
  3. p9 is prepended to Ben's feed cache, a short list of post ids kept in memory (Redis, for example).
  4. Then Chen's feed: write number 2. The cost of a post grows with its author's follower count.
  5. Then Dev's feed: write number 3. The cost of a post grows with its author's follower count.
  6. Eli gets it too: 4 writes for 4 followers. Reading any of these feeds is now a single cache read.

Fan-out on read (pull)

  • At read time, fetch each followee's recent posts and merge.
  • Posting is free; reading is slow for users following thousands.
Ben opens feedAshaChenDevd7 10:12a9 10:05c4 09:30a8 08:40d6 07:15merged newest first; the top 3 are the page
Fan-out on read: pull from everyone you follow, then merge.
  1. Nothing was precomputed. When Ben opens his feed, the feed service reads who he follows: Asha, Chen, Dev.
  2. It queries Asha's recent posts. Each followed account costs a query on every feed load.
  3. Then Chen's: 3 candidates so far. Posting was free, but reading does all the work.
  4. Then Dev's: 5 candidates so far. Posting was free, but reading does all the work.
  5. The 5 candidates are merged by time and the newest 3 returned: d7, a9, c4. Fine for a few hundred follows, slow for thousands.
Push (on write)Pull (on read)
Read latencyLowHigh
Write cost× followersOne write
Celebrity postMillions of writesCheap
Inactive usersWasted writesNothing wasted

The hybrid for celebrities

  • Push for ordinary accounts; above a follower threshold, store once and pull.
  • The reader's feed = cached ids + a few celebrity pulls, merged.
Asha120 followersRavi2,000,000 followersFeed cacheswrites: 120Celebrity postspushstore oncecelebrity = more than 10,000 followersBen's feed:r1 10:02a1 09:50c3 09:10
Hybrid fan-out: push for most accounts, pull for celebrities.
  1. The hybrid: fan out on write for ordinary accounts, but not for celebrities, whose posts would cost millions of writes each.
  2. Asha has 120 followers, under the threshold, so her post is pushed: 120 cache writes, cheap.
  3. Ravi has 2,000,000 followers, so his post is stored once and not pushed: 2,000,000 feed writes avoided.
  4. When Ben opens his feed, the service reads his precomputed cache and pulls the recent posts of the few celebrities he follows.
  5. The two are merged by time. Writes stay bounded for every author, and each read adds only a handful of celebrity lookups.

Ranking and pagination

  • Ranking: take a few hundred candidates, score them (recency, affinity, engagement), return the top. Plain time order is the baseline.
  • Cursor pagination: "older than the last post I saw", never OFFSET.
after p18p21p20p19p18p17p16p15p14p13newest → olderWHERE id < 18 LIMIT 3
Cursor pagination: no repeats when new posts arrive.
  1. Page 1 returns the newest 3 posts, p20, p19, p18, and a cursor naming the last one shown, p18.
  2. While the reader scrolls, p21 is posted and lands at the top. Every older post shifts down one place.
  3. Page 2 by offset skips 3 rows and takes p18, p17, p16: p18 is shown twice, because the list moved under the offset.
  4. Page 2 by cursor asks for posts older than p18: p17, p16, p15. No repeats, no gaps, and an index seek instead of skipping rows.

Bottlenecks and trade-offs

  • Fan-out lag: a queue absorbs bursts; posts appear after seconds, not instantly.
  • Hot feed caches: shard by user id with consistent hashing.
  • Posts table: shard by author; cache hot posts.
  • Deletes and unfollows leave stale ids in caches; filter at read time.

Interview questions

  • Push or pull? Push for most users, pull for celebrities: the hybrid.
  • What goes in the feed cache? Post ids, not bodies, so an edit changes one record.
  • Why cursors? Offsets repeat or skip posts as new ones arrive.
  • How do you rank? Score a candidate set by recency and engagement; time order is the fallback.

Next: Design a Notification System · Before this: Design a Chat App (WhatsApp)

Common questions

What is fan-out on write?

When someone posts, a worker pushes the post's id into the cached feed of every follower. Reading a feed is then a single fast cache read, but one post costs one write per follower, which is expensive for accounts with millions of followers.

What is fan-out on read?

Nothing is precomputed. When a user opens the feed, the service fetches the recent posts of everyone they follow and merges them by time or rank. Posting is cheap, but every feed load does many queries, which is slow for users who follow thousands of accounts.

How do you handle celebrities with millions of followers?

Use the hybrid model. Accounts above a follower threshold are not fanned out; their posts are stored once and pulled at read time, then merged with the reader's precomputed feed. Writes stay bounded and each read adds only a few lookups.

Why use cursor pagination for a feed instead of offset?

New posts keep arriving at the top, so an offset shifts under the reader and repeats or skips posts. A cursor says continue after the last post I saw, which stays correct as the list changes and uses an index seek instead of skipping rows.

Where are feeds stored?

Usually as short lists of post ids in an in-memory store such as Redis, a few hundred per user, with post bodies fetched separately from a post cache or database. Inactive users' feeds can be dropped and rebuilt on their next visit.

← Design a Chat App (WhatsApp) · Design a Notification System →