InterviewKata
System design · Worked design D06 of 46 · Social and content · Long form

Design a news feed

Open a social app and your home feed shows recent posts from the people you follow, in under a second, however many people that is. Behind it is one of the classic trade-offs in system design: do the work when someone posts (copy the post into every follower's feed) or when someone reads (gather posts from everyone they follow)? The answer is "both", and the reason is celebrities. It follows the interview framework phase by phase.

1. The prompt

"Design the home timeline for a social network like Twitter/X or Instagram. Users post, follow other users, and see a feed of posts from the accounts they follow."

Posting and following are simple. The interview is about the read path: making a feed of posts from hundreds of accounts appear in a few hundred milliseconds for 60,000 feed loads a second, when some of those accounts have 100 million followers.

2. Frame the problem

How many users, and how many accounts does a typical user follow?

200M daily users; a few hundred followed accounts on average; some accounts have 100M+ followers.

The spread between normal and celebrity accounts decides the fan-out strategy.

Chronological or ranked?

Ranked, but with a chronological option.

The design produces a candidate set; a ranking service orders it. Ranking internals are out of scope.

How fresh must the feed be?

Followers should see a new post within a few seconds; the author immediately.

Eventual consistency for followers, read-your-writes for the author.

Does the feed include media?

Images and videos, stored separately.

Media goes to blob storage and a CDN (Module 10); the feed carries keys.

Infinite scroll, and how far back?

Infinite scroll; a few days of posts in the feed, older ones via profiles.

Timelines can be capped (say 800 entries), with cursors for paging.

What happens when a post is deleted, or an account goes private?

It must disappear from feeds within seconds.

We need a way to hide a post everywhere at once, without rewriting millions of timelines.

Any read/write ratio hints?

People read feeds far more than they post, roughly 20:1.

Precompute at write time to make reads cheap.

3. What it must do

  1. A user can create a post (text and media).
  2. A user can follow and unfollow other users.
  3. A user can view their home feed of posts from followed accounts, ranked, with infinite scroll.

Not now:

4. How well it must do it

TargetWhy this number
Fast feeds: first page under 300 ms at p99 speedThe feed is the first screen of the app.
Scale: 200M daily users, 60,000 feed loads a second at peak, accounts with 100M+ followers load shapeCelebrity accounts make fan-out wildly uneven.
Fresh enough: followers see a post within ~5 s; the author at once consistency or availabilityAvailability matters more than strict ordering; nobody notices a few seconds.
Deletes are fast: a deleted or hidden post vanishes from every feed within ~5 s security · rulesPrivacy and legal takedowns can't wait for caches to expire.
Posts never lost data safetyFeeds can be rebuilt; posts can't.

5. Numbers that change the design

QuantityWorking→ so we…
Posts200M users × 0.5 posts a day ÷ 10⁵ s~1,000/s; ~3,000/s at peak
Feed reads200M × 10 feed loads a day ÷ 10⁵~20,000/s; ~60,000/s at peak → so reads must be cheap: precompute
Fan-out on write1,000 posts/s × 200 followers on average~200,000 timeline inserts/s → so an in-memory timeline store
One celebrity post100M followers100M inserts for one post → so we don't push celebrity posts
Timeline cache100M active users × 800 post IDs × 8 bytes~640 GB → so a sharded Redis cluster, keyed by user

6. The nouns

posts      post_id (time-ordered, Snowflake-style), author_id, text, media_keys, created_at, status (live | deleted)
follows    (follower_id, followee_id), plus a reverse index followee_id → followers   (sharded by user)
timelines  user_id → [post_id, …]   (latest 800, in Redis sorted sets or lists)
users      user_id, follower_count, is_celebrity (follower_count over the threshold)

7. The contract

REST, with the user from the session token.

POST   /v1/posts                     {text, media_keys}  → 201 {post_id}
POST   /v1/follows                   {followee_id}       → 204
DELETE /v1/follows/{followee_id}                          → 204
GET    /v1/feed?cursor=<post_id>&limit=20               → {posts: [...], next_cursor}
GET    /v1/feed/new?since=<post_id>                       → count of newer posts ("12 new posts")

Post ids are time-sortable (Module 20), so "newest first" is "largest id first", and the cursor is just the last id seen.

8. First working version

A post service with a posts table, a follow service with a follows table, and a feed service that assembles feeds on demand.

8.1 Posting

The post service stores the post once with a time-sortable id and confirms. Media was uploaded straight to blob storage beforehand.

8.2 Following

Insert a row in the follows table, and in the reverse index (who follows this account).

8.3 Reading the feed (pull)

Version one pulls: look up the accounts the user follows, fetch each one's recent posts, merge by id, and take the top 20.

Parked for later (section 9 fixes each)

  1. Pulling 400 accounts' posts on every one of 60,000 feed loads a second is far too slow.
  2. Pushing instead would cost 100M writes for one celebrity post.
  3. Where do timelines live, and what about users who never open the app?
  4. Turning 20 post ids into 20 full posts with authors and counts, quickly.
  5. New posts arriving while someone scrolls.
  6. Deleted posts living on in millions of precomputed timelines.

9. Make it hold up

9.1 Fan-out on write, on read, or both? fast feeds · scale

ApproachWhy
✗ BadPull only: on every feed load, query the latest posts of everyone the user follows and mergeFollowing 500 accounts means 500 lookups (or a huge scatter-gather) per feed load, 60,000 times a second. Too slow and too expensive.
~ GoodPush only: when someone posts, append the post id to every follower's timelineReads become one list fetch. But one celebrity post means 100M writes, delaying everyone's feeds behind it, and most of those followers aren't even online.
✓ GreatHybrid: push posts from normal accounts; for accounts above a follower threshold (say 100K), don't fan out; at read time, merge the user's precomputed timeline with recent posts from the few celebrities they followFan-out work stays bounded; reads add only a handful of lookups (users follow few celebrities), each served from a hot cache. Try the numbers in section 13.

9.2 Storing timelines fast feeds · scale

9.3 Hydrating posts quickly fast feeds

A feed page needs 20 full posts: text, author name and avatar, like counts. Fetch the 20 post objects from a post cache in one batch (MGET), the authors from a user cache, and counters from a counter store; fill misses from the databases. Like counts can be slightly stale (Module 16). The posts table itself is sharded by post id (or author id) in a wide-column or relational store.

9.4 Pagination and freshness fresh enough

Cursor pagination by post id (Module 07) keeps infinite scroll stable while new posts arrive. Posts that arrive after the user opened the app are counted with "newer than the first id I have" and shown behind a "new posts" button, rather than shifting the page under the reader's thumb. The author's own new post is inserted into their own timeline synchronously, so they see it at once.

9.5 Ranking fast feeds

Most feeds are ranked, not purely chronological. Keep the same skeleton:

If ranking is slow or down, fall back to chronological order (graceful degradation, Module 24).

9.6 Deletes and privacy changes deletes are fast

A deleted post must vanish quickly from millions of timelines. Rather than removing it from every list, mark the post deleted and evict it from the post cache: hydration skips it, so it disappears everywhere at once, and timelines are cleaned lazily. The same filter handles blocked users and accounts that went private.

9.7 The whole design after the deep dives

A normal user posts, a celebrity posts, and a follower opens their feed: the hybrid in motion.

10. Interviewer follow-ups

A user follows a new account. When do its posts appear?

Backfill asynchronously: a job copies the account's recent post ids into the follower's timeline (or, for a celebrity, nothing needs copying: they're merged at read time). Unfollow removes them lazily via a filter at hydration.

Where exactly is the celebrity threshold?

Tune it with numbers: fan-out cost (posts × followers) against read cost (celebrities followed per user). Many systems also treat very active posters specially. It's a parameter, not a law.

Traffic grows 10×.

More timeline shards, a stricter inactivity cut-off, more fan-out workers, and a lower celebrity threshold to cap write amplification. Hydration caches scale horizontally.

A celebrity's post goes viral; a million people open it at once.

That post is a hot key in the post cache. Keep it in process memory on feed servers for a few seconds and replicate it across cache shards. Like counters use sharded counters merged periodically (Design D20).

Multi-region?

Posts replicate to every region; fan-out runs per region into regional timeline caches; each user's feed is served from their home region. A few seconds of cross-region lag is within the targets.

The timeline cache shard is lost.

Those users' feeds fall back to pull-and-merge (slower but correct) while timelines are rebuilt from the follow graph and posts in the background. Throttle rebuilds so they don't overload the posts database.

How do you measure that the feed is "good"?

Latency and errors for health; engagement (time spent, interactions) and freshness (age of the newest post shown) for quality; A/B tests for ranking changes.

Edit a post after it's been fanned out?

Timelines hold ids, so edits only change the post object; evict it from the post cache and every feed shows the new version at the next read.

Add trending topics.

Count hashtags and phrases from new posts in a stream processor over sliding windows (say 5 and 60 minutes), compare each with its usual rate so steady giants don't always win, and keep the top few hundred per region in a sorted set refreshed every minute (the heavy-hitters approach of Design D20). Filter spam and coordinated bursts before ranking.

Add search over posts.

Stream new posts into a search index (an inverted index sharded by document, Design D26), with a small real-time index so posts are searchable within seconds and a ranking that weighs recency and engagement. The feed's stores stay the source of truth.

11. When things break

FailureWhat users seeHow we detect itWhat limits the damage
Fan-out workers fall behindNew posts appear lateEvent consumer lagAutoscale workers; pull recent posts for lagging users
Timeline shard lostSlower feeds for some usersCache errors, miss ratePull-and-merge fallback; background rebuild
Ranking service slowChronological feedRanking latency over budgetTimeout and fall back to chronological order
Post cache coldSlow hydrationHit rate dropBatched reads from replicas; warm the hottest posts first
Celebrity posts at the same time as a spikeNothing—Celebrities aren't fanned out; merged at read time from cache

12. Wrap-up and the clock

Trade-offs we made:

What we'd watch:

At 10×:

A 45-minute interview

0–4Frame the problem (follower spread, ranked, freshness)
4–9Must do, how well, numbers (fan-out maths)
9–13Nouns and contract
13–21First working version (pull), parked list
21–40Deep dives: hybrid fan-out (9.1), timelines (9.2), hydration (9.3), deletes (9.6)
40–45Follow-ups and wrap-up

A 60-minute interview

0–5Frame the problem
5–11Must do, how well, numbers
11–16Nouns and contract
16–25First working version
25–50Deep dives 9.1–9.6 and the final picture
50–60Follow-ups: new follows, thresholds, regions; wrap-up
LevelWhat a strong answer shows
Mid-levelPosts, follows and feed APIs; push vs pull explained; a timeline cache; cursor pagination.
SeniorQuantified fan-out, the celebrity problem and the hybrid, hydration with batched caches, inactive users, delete handling.
Staff+Ranking pipeline and fallbacks, threshold tuning, rebuilding timelines, multi-region, cache cost against compute, and how the design evolves with the product.

Common mistakes:

13. Try it, check yourself, read more

Compare the work each strategy does. "Celebrities" are accounts above the threshold; each user follows a few of them.

1,000
200
5
10M
60,000
400
StrategyTimeline writes per secondLookups per feed load

Hybrid assumes each user follows about 5 celebrities, whose recent posts are read from a hot cache at feed time.

Why not fan out a celebrity's posts on write?

Fan-out work is posts × followers; for 100M followers, one post is 100M inserts.

What do precomputed timelines store?

Ids are small; the post is stored once and hydrated from a cache at read time.

How do you make a deleted post vanish from millions of feeds at once?

Every feed read passes through hydration, so one flag hides it everywhere immediately.

How does an author see their own post immediately?

Read-your-writes for the author; everyone else gets it a few seconds later.
ResourceWhy
Designing Data-Intensive Applications, chapter 1Uses Twitter's home timeline as its running example of load and fan-out.
Design a news feed (Hello Interview)Another walkthrough with the hybrid fan-out.