Skip to content
All case studies

Twitter home timeline

Serve home timelines at hundreds of thousands of reads per second. Twitter's answer was fan-out on write into in-memory timelines, with celebrities merged in at read time — a hybrid that bounds both read cost and write amplification.

ClientsLoad balanc…Timeline se…Timeline se…Timeline ca…Timeline st…Tweet storeFan-out que…Fan-out ser…
Arrows show permitted calls. Open the canvas to inspect route programs.
Component labels and connections
  • Clients (client) · calls: Load balancer
  • Load balancer (loadBalancer) · calls: Timeline service 1, Timeline service 2
  • Timeline service 1 (service) · calls: Timeline cache, Timeline store, Tweet store, Fan-out queue
  • Timeline service 2 (service) · calls: Timeline cache, Timeline store, Tweet store, Fan-out queue
  • Timeline cache (cache) · calls: none
  • Timeline store (kvStore) · calls: none
  • Tweet store (database) · calls: none
  • Fan-out queue (queue) · calls: none
  • Fan-out service (worker) · calls: Timeline store

Requirements

Functional

Non-functional

Worked estimates

  • Timeline reads

    the read path must be one lookup, not a query

    reported in 2012: ~300k QPS for timelines

  • Tweets

    small on its own

    reported: ~5k tweets/s average, ~12k/s peak (400M tweets/day)

  • Fan-out writes

    ≈ 1M timeline inserts/s — the fan-out tier is the big write system

    5k tweets/s × ~200 followers average

  • Timeline memory

    ≈ 3 TB of RAM across the Redis fleet; inactive users are not kept

    ~150M active users × 800 IDs × 8 B (+ overhead) × 3 replicas

  • Celebrity

    30M inserts: seconds to minutes of fan-out — hence merge at read time above a threshold

    a tweet from an account with 30M followers

API

POST /2/tweets

Request: { text, media? }

Response: 201 { id }

GET /2/timeline/home?pagination_token=

Request: cursor = last seen tweet ID

Response: 200 { tweets[], next }

Tweet IDs are time-ordered (Snowflake), so the cursor is just an ID.

Data model

tweets is the source of truth, keyed by a Snowflake ID (timestamp + worker + sequence), so IDs sort by time.

timelines holds per-user lists of ~800 tweet IDs (plus author and flags) in memory, replicated 3×; it is a cache of a derived view and can be rebuilt.

The follow graph is a separate service (FlockDB at the time) queried by the fan-out service.

High-level design

Trace permitted calls in the architecture above, then open the reference canvas to inspect routing.

Deep dives

The hybrid model

For most authors, fan out on write: insert the tweet ID into each follower's in-memory timeline (skipping inactive users). For accounts above a follower threshold, skip fan-out; at read time, fetch recent tweets from the celebrities the reader follows and merge them with the precomputed timeline. Reads stay O(1) + a few small queries; writes stay O(followers) for ordinary accounts only.

Timeline storage

Timelines are lists of IDs, capped at about 800, replicated three times in Redis. They are derived data: if a replica is lost it is rebuilt from the tweet store and follow graph, slowly — so the system keeps replicas and avoids flushing them. Hydration (turning IDs into tweets with authors and counts) goes through separate caches with multi-get.

IDs, ordering and pagination

Snowflake IDs (41-bit millisecond timestamp, 10-bit worker ID, 12-bit sequence) are unique without coordination and roughly time-ordered, so merging timelines is a merge of sorted lists and cursors are IDs. Clock skew between workers only reorders tweets within a few milliseconds.

Failure scenarios

The timeline cache is flushed

Scenario and expected result

The front cache restarts empty at t = 1.5 s.

Expected: Reads fall through to the replicated timeline store, which is sized for them, so latency rises briefly and nothing fails. The precomputed store is what makes a cache loss cheap; if timelines had to be recomputed from tweets, the same event would be an outage.

Open this scenario

The fan-out service slows down

Scenario and expected result

From t = 1.2 s to 2.2 s the fan-out workers run 6× slower — the follow-graph service they depend on is degraded.

Expected: Posting and reading are unaffected; the fan-out queue grows and consumer lag rises from near zero to a few hundred milliseconds (seconds, with a longer incident), so new tweets appear late. That is the designed degradation: staleness instead of errors. The lag metric is the freshness SLO.

Open this scenario

A global event triples traffic

Scenario and expected result

From t = 1.2 s to 2.2 s everything triples — a final whistle or an election result.

Expected: Reads stay fast because every read is one cache or store lookup plus a small indexed query. The celebrity merge query is the part that grows with traffic on the tweet store, so the tweet store's utilisation is the one to watch.

Open this scenario

Alternative designs

Reference

  • Inspect the architecture above and run the same scenario.

Pure fan-out on write

  • Every read is one lookup — but a celebrity tweet becomes tens of millions of writes, delaying everyone else's fan-out behind it and bloating timelines that may never be read. The hybrid caps the worst case.

Reference

  • Inspect the architecture above and run the same scenario.

Pure fan-out on read

  • No timeline storage and instant posting, but each read gathers recent tweets from hundreds of followed accounts across shards. At 300k reads/s that is tens of millions of index lookups per second with fan-out tail latency on every request.

Clarifying questions

Common mistakes

Self-assessment rubric

requirements / levels 1-4
  1. 1/4 Post and read.
  2. 2/4 Home vs user timeline.
  3. 3/4 Read/write ratio and freshness target.
  4. 4/4 Explicit staleness budget and celebrity behaviour.
estimates / levels 1-4
  1. 1/4 None.
  2. 2/4 Read and write QPS.
  3. 3/4 Fan-out write rate and timeline memory.
  4. 4/4 Celebrity fan-out time and why it forces the hybrid.
api / levels 1-4
  1. 1/4 Endpoints.
  2. 2/4 With pagination.
  3. 3/4 Cursor by time-ordered ID.
  4. 4/4 Explains why the ID design makes cursors and merges cheap.
data model / levels 1-4
  1. 1/4 Tweets table.
  2. 2/4 Tweets and follows.
  3. 3/4 Precomputed timelines of IDs.
  4. 4/4 Caps, replication and rebuild of derived timelines.
high level / levels 1-4
  1. 1/4 Query on read.
  2. 2/4 Fan-out on write.
  3. 3/4 Hybrid with queue and fan-out service.
  4. 4/4 Hydration caches and failure behaviour of each tier.
deep dive / levels 1-4
  1. 1/4 None.
  2. 2/4 Mentions Redis.
  3. 3/4 Hybrid threshold and read-time merge.
  4. 4/4 Inactive-user skipping, rebuilds and fan-out lag SLO.
wrap-up / levels 1-4
  1. 1/4 Stops.
  2. 2/4 Metrics.
  3. 3/4 Fan-out lag and hot accounts as risks.
  4. 4/4 Concrete freshness SLO and capacity plan for events.