Fan-Out on Write vs Fan-Out on Read (and Fan-Out/Fan-In)

Fan-out on write vs fan-out on read for timelines, Twitter's hybrid for celebrities, and the general fan-out/fan-in pattern for search, feeds and notifications.

Intermediate 7 min read · Updated

Fan-out means turning one action into many: one post written into many followers' feeds, one query sent to many shards, one notification sent to millions of devices. Fan-in gathers the many results back into one. This page covers the famous timeline version (fan-out on write vs fan-out on read, and Twitter's hybrid) and the general fan-out/fan-in pattern used by search, feeds and notifications.

The timeline problem

Push delivers updates in real time but struggles at scale; pull handles millions of clients but adds latency (see push vs pull). A Twitter timeline needs both: instant loads for active users and sensible resource use for hundreds of millions of accounts.

Alice follows 500 accounts; some post constantly, others weekly. When she opens Twitter, her timeline must show the recent tweets of all 500, sorted by time. The simple approach is to query on demand: fetch recent tweets from every followed account, merge, sort, return. That's pull. It works for small follow counts but breaks at scale: querying 500 accounts and sorting thousands of tweets takes time, and every timeline load repeats the work.

Fan-out on write (push)

When Bob tweets, the system immediately writes the tweet into the timelines of all his followers. With 1,000 followers, that's 1,000 inserts into precomputed timelines. When Alice opens Twitter, her timeline is already built: read it and display it, with no merging or sorting. One write creates many copies, and the timeline becomes a cache. Reads are fast because the work happened at write time.

Bob tweets1,000 followersTweets storeFan-out workersvia queueTimeline: AliceTimeline: follower 2Timeline: follower 1,000
Fan-out on write: Bob's tweet is copied into every follower's precomputed timeline, so Alice's read is a single lookup.
  • Pros: very fast, predictable reads; the work happens off the request path.
  • Write amplification: a celebrity with 50 million followers tweets, and the system must write 50 million timelines. One tweet becomes 50 million operations, creating massive write spikes.
  • Storage blow-up: every tweet is stored once per follower timeline; a tweet seen by 10,000 users is stored 10,000 times. Storage grows with follower count × tweet volume, prohibitive for accounts with millions of followers.
  • Wasted work for inactive followers, and edits or deletes must touch many timelines.

Fan-out on read (pull)

Don't precompute. When Alice loads her timeline, fetch recent tweets from all 500 accounts she follows, merge, sort by time and return the top 50. The work happens at read time.

Alice loads timelineTimeline servicemerge + sort, top 50Tweets of account 1Tweets of account 2Tweets of account 500
Fan-out on read: Alice's request queries every followed account, then merges and sorts the results.
  • No write amplification: Bob tweets once and one copy is stored, whatever his follower count. Celebrities and normal users cost the same to write, and storage stays efficient.
  • Expensive reads: every load queries 500 accounts, scans thousands of rows, merges and sorts, and heavy users refresh often. Multiply that by millions of active users.
  • Higher latency: querying hundreds of accounts plus merging can take several hundred milliseconds, and the experience suffers.

The hybrid approach

Twitter uses both, depending on the author. Most accounts have modest followings, so they use fan-out on write: Bob's tweet goes into 1,000 timelines, manageable, and Alice's timeline loads instantly. Celebrities with millions of followers use fan-out on read: their tweets are stored once, and when Alice loads her timeline the system separately fetches recent tweets from the few celebrities she follows and merges them in.

If Alice follows 490 regular accounts and 10 celebrities, her precomputed timeline holds tweets from the 490 (pushed at write time), and at read time the system queries the 10 celebrities and merges. Alice gets fast loads, and celebrity tweets cause no write amplification.

pushpull490 regular accountsfan-out on write10 celebritiesstored onceAlice's precomputed timelineCelebrity tweet cachefew seconds TTLMerge at readtop 50 by timeAlice
Hybrid timeline: regular accounts are pushed into Alice's precomputed timeline; celebrity tweets are pulled and merged when she reads.

The switch-over threshold is a tuning knob, for example 1 million followers (some designs use far lower thresholds such as 10,000; see Design Twitter). Below it, push; above it, pull. The right value balances write cost against read complexity.

Implementation details

  • Track follower counts and switch an account's strategy when it crosses the threshold. The change is gradual: existing timeline entries stay, and new tweets follow the new pattern.
  • Two queries per read: one fetches the precomputed timeline, another fetches recent tweets from high-follower accounts; merge in memory and return the top items.
  • Cache celebrity tweets for a few seconds so many users loading timelines share one query (and the hot key doesn't overload one shard; see hot partitions).
  • Skip inactive users during fan-out. There's no point maintaining timelines for people who haven't logged in for months; build theirs on demand when they return.
  • Store IDs, not full tweets, in timelines, and hydrate content from a cache, so edits show up everywhere; cap timeline length (say the latest ~800 items) and serve older content from a slower path.
  • Rank at read time: modern feeds aren't purely chronological; candidates from the precomputed timeline are scored by a ranking model. Use cursor pagination so new posts don't shift pages.
Push (fan-out on write)Pull (fan-out on read)Hybrid
Read latencyLowestHighLow
Write costFollowers × posts1 per postBounded (no celebrity fan-out)
StorageOne copy per followerOne copyCopies only for regular accounts
Celebrity postsVery slow fan-outFineFine (pulled)
FreshnessSeconds behind (async)Real timeMostly seconds behind
Best whenReads far exceed writesWrites would amplify enormouslyFollower counts are highly skewed

Fan-out on write optimizes reads at the expense of writes, right for most users, who read far more than they post. Fan-out on read optimizes writes at the expense of reads, right for celebrities, whose posts would otherwise reach millions of timelines. The hybrid optimizes the common case and handles the edge case differently, and the idea applies to any system with a highly skewed distribution: e-commerce recommendations, social networks, content feeds.

The general fan-out/fan-in pattern

Beyond timelines, fan-out splits one request into many parallel sub-requests, each handled independently by a different server or shard, and fan-in collects their results into one response. When Alice (following 300 people) loads her timeline on a pull path, the system fans out to fetch recent tweets from each followee; running those queries in parallel across 10 database shards cuts latency from seconds to milliseconds. The pattern appears as parallel reads (feeds, search) and parallel writes (notifications to millions of inboxes).

RequestFan-outShard 1Shard 2Shard 3Shard NFan-inmerge resultsResponse
Fan-out/fan-in: one request is split into parallel sub-requests across shards, and the partial results are combined into one response.

Fan-out reads

Search engines are the classic case. A query for "system design" searches billions of documents in an index split into 100 shards. The query goes to all 100 at once; each returns its top 10 matches; fan-in merges the 1,000 results into the global top 10. Sequentially, at 50 ms per shard, that would take 5,000 ms. In parallel, the total is roughly the slowest shard plus the merge, on the order of 50–100 ms: a 50× speedup that makes search practical. Product search works the same way: "laptop under $1000" is filtered by price and category on every catalog shard, then merged by relevance. See search.

Sequential (100 × 50 ms)5,000 msParallel fan-out~50–100 ms
Querying 100 shards at 50 ms each: one after another versus all at once.

The catch is stragglers: if 99 shards answer in 50 ms and one takes 500 ms, the whole request waits for it. Fixes include timeouts with partial results, backup requests to replicas, and hedged requests (ask several replicas, use the first answer). See latency vs throughput.

Fan-out writes

A user posts a photo and every follower gets a notification. For a celebrity with 10 million followers, writing 10 million notifications one by one is impossible in reasonable time. Fanning the writes out across hundreds of servers, each handling about 50,000, brings it from hours to seconds. Twitter's home timeline is the same idea (fan-out on write into follower inboxes), with the celebrity exception above.

Celebrity posts10M followersWork queuebatches of 50,000Worker 1Worker 2Worker 200Follower inboxes
Fan-out writes: a post is split into batches on a work queue, and many workers write follower notifications in parallel.

Aggregation strategies (fan-in)

StrategyHow it combinesExample
Merge sortMerge pre-sorted lists, keeping the orderSearch results ranked by relevance from each shard
UnionCombine everything, removing duplicatesPosts from several friend groups, deduplicated by post ID
IntersectionKeep only results present in every set"red laptop" = results for "red" ∩ results for "laptop"
Aggregation (sum, count, average)Combine numbersTotal orders = sum of each region's count

Handling failures

When you query 100 shards, one will eventually fail. The choice is to wait indefinitely, time out and fail, or return partial results:

  • Partial results keep the service available: if 99 of 100 shards answer, return those with a flag. Search engines do this routinely; a missing shard costs 1% of results, not the whole query.
  • Timeouts stop one slow shard from blocking everything: set a deadline such as 100 ms, include whoever answers in time, and accept slightly incomplete results for bounded latency.
  • Backup requests: send to the primary; if it hasn't answered in 50 ms, send to a replica and use whichever answers first. Masks slow or failed nodes with little extra load.
  • For fan-out writes, use work queues so batches can be retried, and make each write idempotent so retries don't duplicate notifications. See idempotency.

Where it’s used

Twitter / X

Historically pushed tweets into Redis-backed home timelines for most users, and merged in tweets from high-follower accounts at read time.

Instagram and Facebook

Precompute candidate posts from followed accounts (fan-out on write), then rank them with ML models at read time.

Search engines

Every query fans out to all index shards and fans in by merging top results, with timeouts and partial results for stragglers.

Notification systems

One event fans out to millions of devices through work queues and parallel workers.

In an interview

  • For a feed, present push and pull, their costs, then the hybrid with a follower threshold for celebrities.
  • Quantify write amplification (followers × posts per day) and do the fan-out asynchronously through a queue.
  • For search or aggregation, describe fan-out/fan-in across shards, the merge strategy, and how you handle stragglers (timeouts, partial results, hedging).
  • Mention skipping inactive users, caching celebrity tweets, and idempotent fan-out writes.

Further reading