STANDARDwalkthrough
Fanout-on-Read
What if writes were free and we computed timelines only when someone opens the app? The constraint: fanout-on-write breaks for users with millions of followers because one post triggers millions of cache writes.
When a user requests their timeline, our system fetches posts from all followed accounts, merges them, sorts by timestamp, and returns the top results. Writes are trivially cheap: one INSERT into the post store, done.
“We need an approach where write cost is constant regardless of follower count. Fanout-on-read stores each post exactly once in the author's post list.”
No fan-out, no follower iteration, no write amplification. But reads become expensive.
A user following 200 accounts forces a 200-way merge on every timeline request. Implication: at 200 million DAU with an average of 10 feed opens per day, that is 2 billion merge operations daily, each touching 200 data sources.
We chose fanout-on-read (not fanout-on-write) specifically for celebrity accounts because their follower counts make write-time fanout prohibitively expensive. Trade-off: we gave up fast reads in exchange for write cost.
Timeline reads take 200-500ms depending on the number of followed accounts and cache hit rates, compared to sub-10ms with fanout-on-write. Facebook uses fanout-on-read for certain feed types because their social graph is denser (average 338 friends) and bidirectional, making write-time fanout impractical for users with thousands of mutual connections.
What if the interviewer asks: 'How do we reduce the read latency?' We fetch followed accounts in parallel (not sequentially), cache individual post lists with a 60-second TTL, and limit the merge to the most recent 200 posts per account.
Related concepts