What is feed fanout and what are the push vs pull approaches?
Feed fanout is the mechanism by which a post from one user is delivered to the feeds of all their followers. At small scale this is trivial; at Twitter/Instagram scale, a single post from a celebrity with 50 million followers must fan out to 50 million feed entries — a massive write amplification problem.
**Fanout-on-write (push model)**: When a user publishes a post, a background job immediately writes the post ID into each follower's feed cache (usually a Redis sorted set keyed by timestamp). Feed reads are O(1) — just fetch the pre-built list. The cost is write amplification: one post triggers millions of cache writes. For most users with <10K followers this is fine. For celebrities, a single tweet could overwhelm your write path.
**Fanout-on-read (pull model)**: The feed is computed lazily when the user opens their app. The system fetches the list of accounts the user follows, retrieves recent posts from each, merges and sorts them. No write amplification, but read latency is high and proportional to following count. Not viable for users who follow thousands of accounts.
**Hybrid approach** (what Twitter and Instagram actually use): Apply push to normal users (following count < threshold, e.g. 1M followers). Apply pull to celebrity accounts. When building a feed, merge the pre-built push cache with a real-time pull from celebrity accounts. The threshold is tunable — when a celebrity posts, you skip the fanout and let readers pull at read time.
Storage: each user's feed is typically a Redis sorted set of post IDs with the score as a timestamp. Only IDs are stored, not full post content — a separate lookup fetches post data. Feed length is capped (e.g., 800 entries) and older entries are evicted.
**Backfill and consistency**: new followers don't automatically get historical posts unless you backfill. Unfollows must purge entries — or tolerate stale entries with a grace window. These edge cases are often handled asynchronously.
At the infrastructure level, fanout jobs run as async workers (Celery, Kafka consumers, Sidekiq). Slow workers cause delivery lag — a post may appear in some feeds seconds before others, which is acceptable eventual consistency for social feeds.
| Aspect | Fanout-on-Write (Push) | Fanout-on-Read (Pull) |
|---|---|---|
| Write cost | High — one write per follower | Low — no writes on publish |
| Read latency | O(1) — pre-built cache | O(following_count) — computed on demand |
| Storage | High — copies of post ID per follower | Low — store once, compute per read |
| Stale data risk | Low — feed updated at publish time | Higher — depends on cache TTL or freshness policy |
| Celebrity problem | Catastrophic write amplification | Handles naturally — one post, many readers pull |
| Implementation complexity | Higher — async fanout workers needed | Lower to start, harder to scale at read time |
| Used by | Twitter (non-celebrities), Instagram | Twitter (celebrities via hybrid), RSS readers |
Correctly defines both push and pull models with their core trade-offs (write amplification vs. read latency) and mentions the celebrity/high-follower-count edge case.
Covers the hybrid model with a concrete threshold-based approach, explains the Redis sorted set data structure for feed storage, addresses backfill and unfollow edge cases, and mentions async fanout workers.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment