requirements

A social feed app — call it Ripple — lets users post short updates and see a feed of posts from accounts they follow. This is a classic case study specifically because the obvious naive design (compute each feed on demand) falls apart at exactly the point where one account gets very popular.
FunctionalNon-functional
Post a short updateFeed loads must be fast, even for a user following thousands of accounts
Follow/unfollow other accountsThe system must handle a small number of accounts with an enormous follower count without falling over
View a reverse-chronological feed of followed accounts' postsNew posts should appear in followers' feeds within seconds

approach 1: compute the feed on read ("pull")

The naive approach: when a user opens their feed, query "give me the most recent posts from everyone I follow," merge, and sort by time. This is simple and always up to date, but the cost scales with the number of accounts followed — a user following 3,000 accounts triggers a fan-out read across 3,000 authors' post histories on every single feed load.

approach 2: precompute the feed on write ("push", fan-out-on-write)

The opposite approach: when someone posts, immediately push a copy of that post into the precomputed feed of every one of their followers, so a feed load becomes a single fast read of an already-assembled list — closer in spirit to the publish-subscribe fan-out pattern, with each follower acting like a subscriber.
This makes feed reads extremely fast, which matters because reads (people checking their feed) vastly outnumber writes (people posting) — the same read-heavy skew seen in the URL shortener case study. But it inverts the cost: posting now means writing to every single follower's feed, which is fine for a normal account and catastrophic for an account with 50 million followers — one post would trigger 50 million writes.

the distinctive component: a hybrid for celebrity accounts

Neither pure approach works well across the whole range of account sizes, so real feed systems use both, chosen per-author:
Author's follower countStrategy usedWhy
Typical account (fewer than ~10K followers)Fan-out-on-write (push)The write cost is small and bounded, and it keeps feed reads for that account's followers fast.
Celebrity/high-follower accountFan-out-on-read (pull) for that author specificallyPushing to millions of followers on every post would be enormous write amplification for one post — instead, that author's posts are merged in at read time.
A follower's feed load becomes: read their precomputed feed (fast, covers everyone they follow who uses push), then separately fetch and merge in recent posts from any celebrity accounts they follow (pull, but only for a small number of high-follower accounts) — combining both strategies rather than picking one globally.

where the precomputed feed actually lives

A user's precomputed feed is a natural fit for a key-value store — the access pattern is always "fetch by user ID," and the value is just an ordered list of recent post IDs, capped at a few hundred entries with older ones trimmed off. This keeps each user's feed cheap to store and fast to read, at the cost of the feed being an eventually-consistent, precomputed view rather than a live, always-authoritative query — the same trade-off from Consistency Models applied here: a feed a few seconds stale is a completely acceptable cost for the write-amplification savings.

evaluation

RequirementHow it's met
Fast feed loads at scaleFan-out-on-write means most feed reads are a single fast key-value lookup, not a live fan-out query.
Doesn't collapse on celebrity accountsFan-out-on-read specifically for high-follower authors avoids write-amplifying a single post to millions of feeds.
New posts appear quicklyPushed posts land in followers' feeds essentially at write time; pulled posts are fetched fresh at read time.

related topics

reference