Skip to main content
intermediate

Twitter/X timeline

Timeline generation with hybrid fan-out — push for regular users, pull for celebrities.

Ch 0The scenario
Journey map
Twitter/X timeline 1 chapters · ~5 min total
Levels:L4 · BeginnerL5 · IntermediateL6 · AdvancedL7 · Senior
1
Foundation
Set the stage. Requirements, math, API contract.
~5 min
The full journey
1 chapters · beginner → super-senior
BeginnerIntermediateAdvancedSenior
Ch 0 · StartClick any chapter to jump →Ch 12 · Defense
Chapter 0
For beginner
5 min read

The scenario

The archetypal feed system — hybrid fanout, hot celebrities, and the 143,199 TPS record

Your mentor

Same startup, same engineer #4. Fourth Monday of the year.

Your CTO drops by your desk with coffee. "Marketing loves the URL shortener and Slack, and Instagram is in beta. Now they want something more ambitious — a public microblogging feature. Users post short text and media. Followers see them in a reverse-chronological timeline. Handles like @jane. Direct messages. Ship an MVP in 12 weeks."

She pauses. "And by the way — one of our early beta users has 8 million followers. She just tweeted, and our L4 architecture melted."

That's the whole game.

Here's the pattern you've been building toward:

URL Shortener was read-heavy with tiny fanout (redirect happens 1:1).

Slack was real-time write-heavy but bounded fanout (channel of ~100 members).

Instagram shifted the paradigm — the ranking became the product, and follows became one signal among 50.

Twitter is the archetypal fanout problem. Every tweet from a regular user with 200 followers = 200 timeline writes. Every tweet from a celebrity with 50 million followers = 50 million writes. The push-fanout that works for 99% of users breaks catastrophically for 1% who drive 90% of engagement. Understanding this cliff — and how Twitter engineered around it — is the whole 12 chapters.

The real 2024 numbers

Before we design anything, know the real scale you're designing against:

  • ~610M MAU (Reuters, Feb 2025), down from 250M+ DAU pre-2022
  • ~500M tweets/day at peak (2013 peak was 500M/day, ~5,700 TPS average)
  • Record peak: 143,199 TPS — set during a "Castle in the Sky" broadcast in Japan, 2013 (Twitter Engineering blog, 2013)
  • Recent peak: 24,400 TPS — 2022 FIFA World Cup Final (Twitter Engineering, 2022)
  • Top account (as of 2024): @elonmusk with 200M+ followers; @BarackObama with 130M+ (Wikipedia list)
  • Timeline reads: ~10 billion/day at peak (2015)
  • Read:write ratio: ~1000:1

Why 143,199 TPS is the interview soundbite: it was NOT sustained — it was a peak from a synchronized cultural event where an entire country tweeted the same word at the same second. Twitter's steady-state is much lower. Real interview greatness = knowing that number AND knowing when to say "but the sustained rate is closer to 6K TPS."

The whole journey at a glance

Every 10× in follower count forces a fundamentally different fanout strategy:

text
═══════════ TWITTER ARCHITECTURE ACROSS 4 SCALES ═══════════ L4 (10K users) L5 (10M users) L6 (500M users) L7 (X-scale, all-time) max ~10K followers max ~100K follwrs max ~50M followers max ~200M (Musk) 12 weeks · $500/mo 6 months · $50K/mo 18 months · $500K/mo ongoing · $1B+/yr ┌────────┐ ┌────────┐ ┌── Global CDN ──────┐ ┌── Own CDN + AI ────┐ │ Web │ │ Web │ │ timeline + media │ │ media + Grok LLM │ │ Mobile │ │ Mobile │ │ edge caches │ │ edge inference │ └───┬────┘ └───┬────┘ └─┬──┬──┬──┬─────────┘ └──┬──┬──┬──┬──────┘ │ │ │ │ │ │ │ │ │ │ ┌──▼───┐ ┌──▼──┐ ┌──▼──▼──▼──▼─────┐ ┌──▼──▼──▼──▼──────┐ │ ALB │ │ ALB │ │ Multi-region │ │ 20+ regions + │ │ HTTPS│ │ WSS │ │ ALB · anycast │ │ anycast + BGP │ └──┬───┘ │ HTTPS│ └───┬──────┬──────┘ └────┬──────┬──────┘ │ └──┬──┘ │ │ │ │ ┌──▼──────┐ ┌───▼─────────┐ ┌──▼──────▼─────┐ ┌─────▼──────▼──────┐ │ 1 API │ │ API pods │ │ Regional │ │ Hybrid fanout │ │ server │ │ sharded by │ │ API + │ │ service: │ │ │ │ user_id │ │ hybrid │ │ push < 10K │ └──┬──────┘ │ │ │ fanout │ │ pull > 10K │ │ └───┬─────────┘ │ service │ │ celebrity model │ │ │ └───┬───────────┘ └──┬──┬──┬──┬───────┘ │ ┌───▼──┐ ┌───▼──────────┐ │ │ │ │ │ │Redis │ │Redis Cluster │ ┌──▼──▼──▼──▼─────┐ │ │timeln│ │timeline cache│ │Timeline Service │ │ │cache │ │per-region │ │(the OLD Manhattan) │ └───┬──┘ └───┬──────────┘ │+ RedisCluster │ │ │ │ └──┬──────────────┘ ┌──▼───┐ ┌───▼─┐ ┌──▼──────────┐ │ │MySQL │ │MySQL│ │Sharded MySQL│ ┌──▼──────────────┐ │(user+│ │+ 2 │ │+ Manhattan │ │Manhattan (2016+)│ │ tweet│ │repl │ │Twitter's KV │ │KV store built at│ │+follow │icas │ │store (retire│ │Twitter 2014-16 │ │Multi-│ │+ Kaf│ │d 2022 for X)│ │+ HDFS + Kafka + │ │AZ) │ │ka │ └─────────────┘ │ Flink for search │ └──────┘ └─────┘ └─────────────────┘ ↑ ↑ ↑ ↑ Boring Fan-out on write Hybrid: push for regular Multi-region. pull-based for regular users. followers, pull-merge Real-time search. JOIN works. Kafka for celeb for celebrities on read. Grok LLM inference events. Manhattan KV store is compute-bound, + Redis Cluster. not I/O bound. Chapter 5 Chapters 6+6.5 Chapter 7+7.5 Chapter 8 walks walks through walks through walks through through push-fanout + the hybrid model, X's post-2022 L4 pull Redis timeline Manhattan history, reorg + Grok + timeline in cache and the celebrity multi-region full cliff at 10K followers economics Key insight: 99% of Twitter users are fine with push fanout. 1% (celebrities) destroy the model. Twitter's ANSWER: HYBRID. Push for followers < 10K, pull-merge celebrity tweets at read time. That's the entire architecture story.

The same 4 tiers as clean architecture diagrams

The ASCII compressed all four tiers. Here are the same shapes as clean Mermaid — the kind an interviewer expects on a whiteboard:

L4 · 10K users · pull-based JOIN · $500/mo · 12 weeks:

flowchart TD W([Web / Mobile clients]) -->|HTTPS| LB[ALB<br/>$25/mo] LB --> API[1 API server<br/>c5.large<br/>~1K RPS timeline] API --> PG[(MySQL Multi-AZ<br/>users + tweets + follows<br/>$150/mo)] API -->|presigned PUT| S3[(S3<br/>media binaries)] classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a class LB,API,PG,S3 n

L5 · 10M users · push-fanout for everyone · $50K/mo · 6 months:

flowchart TD W([Web / Mobile]) -->|HTTPS + WSS| LB[ALB · WebSocket for realtime] LB --> R{User-affinity<br/>router<br/>hash by user_id} R --> A1[API 1] R --> A2[API 2] R --> A3[API 3] A1 --> KF[Kafka<br/>tweet-created events] KF --> FW[Fanout workers<br/>write to N follower timelines] FW --> RD[(Redis timeline cache<br/>list of tweet_ids per user)] A1 --> RD A2 --> RD A3 --> RD A1 --> PG[(MySQL primary<br/>+ 2 read replicas<br/>tweets + follows source-of-truth)] classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a classDef c fill:#fef3c7,stroke:#d97706,color:#78350f class LB,R,A1,A2,A3 n class KF,FW,RD,PG c

L6 · 500M users · hybrid push/pull · $500K/mo · 18 months:

flowchart TD W([Global users]) -->|HTTPS anycast| CDN[Global CDN] CDN --> LB[Regional ALB<br/>us-east · eu-west · ap-northeast] LB --> API[Regional API pods] API --> HFS[Hybrid Fanout Service<br/>push if follower &lt; 10K<br/>pull-merge celebs on read] HFS --> RC[(Redis Cluster<br/>per-region timeline cache<br/>tweet_ids for 500M users)] HFS --> MAN[(Manhattan KV store<br/>Twitter's built-2014<br/>tweet metadata)] HFS --> C[(Cassandra tier<br/>social graph shards)] API --> ES[Elasticsearch<br/>real-time search index] API --> KFA[Kafka + Flink<br/>ML signals + search index] classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a classDef m fill:#fce7f3,stroke:#be185d,color:#831843 class CDN,LB,API,RC n class HFS,MAN,C,ES,KFA m

L7 · 610M+ MAU · X-scale + Grok LLM + custom silicon · $1B+/yr:

flowchart TD W([Global users]) -->|HTTPS anycast| CDN[X's Own CDN<br/>edge caches + media + Grok] CDN --> LB[20+ regional ALBs] LB --> API[Regional API] API --> HFS[Hybrid Fanout Service] HFS --> GROK[Grok LLM inference<br/>reply suggest · search · rank<br/>on H100/H200 GPUs] HFS --> RC[(Redis Cluster<br/>timeline cache)] HFS --> MAN[(Manhattan KV<br/>tweet + user metadata)] API --> ES[Search index<br/>Elasticsearch/OpenSearch] API --> SC[Streaming compute<br/>Kafka + Flink<br/>ranking signals<br/>trending topics] API --> C[(Cassandra multi-region<br/>replicated 3x)] classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a classDef m fill:#fce7f3,stroke:#be185d,color:#831843 classDef ml fill:#dcfce7,stroke:#16a34a,color:#14532d class CDN,LB,API n class RC,MAN,C,ES m class HFS,GROK,SC ml

Why every 10× breaks the architecture

Look at the four tiers side by side. Two patterns dominate:

  1. Storage stays boring. MySQL → Sharded MySQL → Manhattan + Cassandra. Boring engineering, and it's fine.
  1. Fanout mutates. L4 pull → L5 push → L6 hybrid → L7 hybrid + ML rerank. The fanout strategy IS the architecture.

The celebrity cliff: at ~10K followers, push-fanout starts costing more than pull-merge on read. Twitter engineered a hybrid ~2012: push if followers < 10K, pull-merge everyone else's celebrity tweets at read time. Reference: Twitter Engineering: "The Infrastructure Behind Twitter: Scale".

Why not push everything? At Elon's 200M followers, a single tweet = 200M timeline writes. Even at 10K writes/sec/node = 20K node-seconds = 5.5 hours to fully fan out. Pull-merge on read is O(N) reads at 200M × ~5% online = 10M timeline requests over a few hours. Cheaper, faster, correct.

Why not pull everything? At L5 with 10M users each following 200 users, every timeline read = 200 tweet_id fetches = 200 Redis calls. Redis handles this, but ballooned reads at billions per day = massive Redis costs. Push is dramatically cheaper for the 99% of users with < 10K followers.

The 3 senior insights before we start Chapter 1

  1. The problem is NOT storage — it's the fanout curve. Every candidate memorizes "we shard MySQL." That's fine. What Twitter engineered is the decision boundary between push and pull, which is more interesting than any DB choice.
  1. Manhattan is NOT Cassandra. Twitter built its own KV store (Manhattan) in 2014 for tweet metadata — because Cassandra's eventual-consistency semantics didn't fit their SLA. Reference: Twitter Engineering: "Manhattan, our real-time, multi-tenant distributed database". Do NOT say "Twitter uses Cassandra for tweets" — that's a common tutorial-parrot mistake.
  1. The 143K TPS record is a peak, not a baseline. Baseline is ~6K TPS. Interviewers love asking "how do you handle 143K TPS?" — the right answer is "we don't design for that; we design for the 24K TPS World Cup peak (sustained ~30 min) and let Kafka queue absorb the microsecond bursts."

Chapter map for the journey ahead

  • Chapter 1 — Requirements (functional + non-functional per level)
  • Chapter 2 — Capacity estimation (610M MAU, 500M tweets/day, 10B timeline reads/day)
  • Chapter 3 — API design (tweet, timeline, follow, DM, search)
  • Chapter 4 — Data model (users, tweets, follows — and the graph problem)
  • Chapter 4.5 — The follows graph: adjacency list vs graph DB vs materialized fanout
  • Chapter 5 — L4 MVP: pull-based JOIN. Works up to ~10K users
  • Chapter 6 — L5: push-fanout with Kafka + Redis
  • Chapter 6.5 — The celebrity cliff. Hybrid push/pull decision matrix
  • Chapter 7 — L6: Manhattan KV store, Redis Cluster, multi-region
  • Chapter 7.5 — The tweet ranking + search pipeline (Elasticsearch + Flink)
  • Chapter 8 — L7: X-scale + Grok + real-time ML reranking
  • Chapter 9 — Failure modes: celebrity death spiral, timeline cache stampede, follow-graph inconsistency
  • Chapter 10 — Trade-off matrix
  • Chapter 11 — Interview masterclass: 45-min mock, questions to ask
  • Chapter 12 — Defense: the 20 hardest interview questions on Twitter

Ready? Chapter 1 next: what did the CTO actually ask for?

Key takeaway

Twitter/X at 610M MAU is a fanout problem, not a storage problem. 99% of users work with push-fanout; 1% (celebrities) require pull-merge on read. The hybrid decision (push if followers < 10K, else pull) is Twitter's architectural signature — and Manhattan (not Cassandra) is the KV store that made it work. The 143,199 TPS peak is a soundbite; steady-state is 6K TPS.

You should now be able to answer
  • Why is Twitter fundamentally a fanout problem, not a storage problem?
  • What is the celebrity cliff and where is it (10K followers)?
  • What's the difference between push, pull, and hybrid fanout?
  • What is Manhattan and why did Twitter build it instead of using Cassandra?
  • What's the difference between 143K TPS peak and 6K TPS steady-state?
Concept deep-dives referenced in this chapter

Every concept below has its own interactive, animated page in the Learning Tracks section. Read them any time you want to go deeper than the mentor prose above — they're the reusable foundation this chapter is built on.

Coming next

Chapter 1 next: what did the CTO actually ask for? Post a tweet, read a timeline, follow, DM — each has functional and non-functional requirements. Get these wrong and you'll design the wrong system for the whole 12 chapters.

Components used in this design

Study each component's deep dive to understand it in isolation.

Load Balancer
load-balancer

Distributes incoming traffic across a pool of servers for scale and fault tolerance.

CDN (Content Delivery Network)
cdn

A globally distributed cache that serves static and cacheable dynamic content close to the user.

Redis
cache

An in-memory key-value store used for caching, pub/sub, rate limiting, distributed locks, and simple queues.

SQL Database
sql-db

A row-oriented, ACID-compliant relational database — the default for transactional workloads.

NoSQL Database
nosql-db

Umbrella for document, wide-column, and key-value stores optimized for horizontal scale over strict schema.

Kafka
stream

A distributed, partitioned, replicated commit log for event streaming, high-throughput ingest, and decoupled services.

API Gateway
api-gateway

Single entry point that handles auth, rate limiting, routing, and protocol translation for downstream services.

Object Storage (S3, GCS, Azure Blob)
object-storage

Durable, cheap, flat-namespace storage for blobs — images, videos, backups, logs, and any large binary object.

Search Engine (Elasticsearch, OpenSearch, Meilisearch)
search

Inverted-index-based full-text and structured search — the right tool for 'find me records matching this query' when SQL LIKE isn't fast enough.

Rate Limiter
rate-limiter

Enforces per-caller (per-user, per-IP, per-tenant) request budgets to protect downstream systems from abuse and overload.

Stream Processor (Flink, Kafka Streams, Spark Structured Streaming)
stream

Continuous computation over event streams — windowed aggregations, joins, ML features, and event-driven derived views.

Service Discovery (Consul, etcd, DNS-based)
coordinator

How services find each other in a dynamic fleet — because IPs change, nodes come and go, and hardcoding is a losing game.

Workflow Engine (Temporal, Cadence, AWS Step Functions)
workflow

Orchestrates long-running, stateful multi-step processes — the right tool when a business flow involves many services and can span days.

Patterns applied in this design

Study each pattern's deep dive for the recurring solution logic.

Explore next — related systems

If you enjoyed this problem, these share similar patterns or challenges.