Twitter/X gets hard not when one tweet is stored, but when that one write must turn into a fresh feed for millions of followers under an overwhelmingly read-heavy workload.
The chapter ties together fan-out strategy, home timeline caching, search, trends, and celebrity-account handling into one working architecture.
For interviews and architecture discussions, this case is useful because it forces you to explain where freshness can lag, how to survive very large accounts, and why one strategy does not fit every path.
Fan-out Strategy
The key choice is not the database first, but when tweets should be pushed into ready-made feeds and when they should be assembled on read.
Home Timeline Cache
The hottest read path usually depends on a prebuilt home timeline, or the cost of each request grows too quickly.
Streaming Trends
Detecting discussion spikes needs its own streaming path that can count fast without drowning in memory cost or noise.
Celebrity Accounts
Very large authors break naive fanout-on-write, which is why they almost always need a separate handling mode.
Introduction
Designing Twitter/X is not mainly about storing tweets. It is about keeping the home timeline fresh for millions of followers under a workload that is overwhelmingly read-heavy. The core architectural fork is deciding when fanout-on-write is worth the cost and when fanout-on-read is the safer option.
Functional Requirements
- Tweet publishing — a short text post, media, and the basic interaction model around it.
- Home timeline — a personalized feed built from accounts the user follows.
- User timeline — the complete tweet history of one author in reverse chronological order.
- Follow and unfollow — updates to the social graph.
- Likes and retweets — engagement actions and counters.
- Search — search across tweets, accounts, and keywords.
- Trending topics — fast detection of emerging discussion spikes.
- Notifications — mentions, replies, likes, and other activity around the account.
Non-functional Requirements
The user-facing priorities are low timeline latency, a predictable freshness window, and enough resilience to survive partial failure without large visible outages. Perfect consistency is not required here: a small delay before a tweet appears for all followers is usually acceptable.
- Scale: roughly 500M registered users and 200M DAU.
- Write volume: around 500M new tweets per day.
- Traffic shape: reads outnumber writes by about 1000:1.
- Home timeline latency: ideally under 200 ms.
- Freshness window: 5-10 seconds of propagation delay can be acceptable.
- Availability: a 99.99% target is reasonable, but the important part is graceful degradation instead of all-or-nothing failure.
- Celebrity problem: publish flow must survive accounts with tens or hundreds of millions of followers.
Traffic estimate: 200M DAU × 100 timeline reads per day is roughly 20B reads per day, or about 230K QPS on the read side. 500M tweets per day is about 6K write QPS.
Core Problem: Feed Generation
The main architectural problem in Twitter/X is how to assemble the home timeline fast enough and cheaply enough when almost every tweet may need to reach many followers. At a high level, you either push tweets into ready-made timelines or you assemble the timeline on read from the latest tweets of the accounts a user follows.
Fanout-on-Write (Push)
As soon as a tweet is published, it is written into the cached timelines of the followers.
- Fast reads because the timeline is already assembled.
- Simple logic on the read path.
- Expensive publishes for very large accounts.
- High storage cost because entries are duplicated.
- Some work is wasted on inactive followers.
Fanout-on-Read (Pull)
The timeline is assembled at request time by loading recent tweets from followed accounts and merging them into one response.
- Publish cost is almost independent of follower count.
- Less duplication in storage.
- No background work for inactive users.
- The read path becomes heavier and touches more sources.
- Merge and filtering logic become part of the request path.
Hybrid Approach
In practice, Twitter/X uses a hybrid strategy: ordinary accounts use fanout-on-write, while very large accounts lean on fanout-on-read. That keeps the system from exploding on write amplification when one tweet would otherwise need to be copied into a massive number of personal timelines.
Hybrid Feed Architecture
Switch modes to highlight the path for ordinary accounts or high-follower authors.
Tweet Intake
API and media upload
Tweet Service
store tweet and choose strategy
Fan-out Service
write into follower timeline caches
Home Timeline Cache
Redis ZSET per user
Celebrity Store
separate path for very large accounts
Read-Time Merge
combine with the prepared feed
Timeline Service
rank, filter, and deliver
How celebrity accounts are handled
The threshold can be approximate, for example 10,000 followers. Once an account is above that level, the system avoids eagerly copying every new tweet into every follower timeline. Instead, the tweet is stored separately and merged into the home timeline during reads.
Home Timeline Cache Architecture
The timeline cache exists to make the hottest read path cheap. In most designs, publish is acknowledged quickly while the actual fan-out work moves into background processing so the user is not blocked on all downstream writes.
Timeline structure in Redis
# Each user has a dedicated home timeline in Redis
# Key: timeline:{user_id}
# Value: Sorted Set (score = timestamp, member = tweet_id)
ZADD timeline:12345 1705234567 "tweet_abc123"
ZADD timeline:12345 1705234890 "tweet_def456"
# Read the latest 100 tweets
ZREVRANGE timeline:12345 0 99
# Approximate storage estimate:
# 200M users × 800 tweets × 8 bytes = 1.28 TB
# With replication ×3 = about 4 TB Redis clusterCache limits
- The cache usually keeps only the latest 800 tweets per user.
- Older entries are evicted by rank.
- Deep history is fetched from the primary data store.
Fan-out workers
- Run asynchronously so publish ACK is not blocked.
- Batch updates to reduce write amplification.
- Need retries and duplicate-safe processing.
Trending Topics
Trend detection is a stream-processing problem. The system cares about bursts of discussion rather than absolute tweet count, so it needs approximate counting, time windows, and spam filtering that all move with the stream.
Trending Pipeline
Click a stage to highlight the corresponding part of the pipeline.
Tweet Stream
Kafka topic
Entity Extraction
hashtags and entities
Filtering
spam and stop words
Trend Scoring
windows and decay
Trend Cache
Redis sorted sets
Count-Min Sketch
A probabilistic data structure that lets you count millions of hashtags without a heavy exact table for every key. The trade-off is a small approximation error in exchange for low memory cost.
Sliding window
The system usually watches the last 5-15 minutes and gradually decays old events. That makes it easier to detect a real spike instead of a topic that has been slowly accumulating for hours.
Trend Scoring Formula
# Simplified Twitter trend score
def calculate_trend_score(topic, current_window):
# Current velocity: tweets per minute over the last 5 minutes
current_count = count_in_window(topic, minutes=5)
# Baseline: average number of tweets per 5-minute bucket over 7 days
baseline_count = get_baseline(topic, days=7)
# How much faster the topic grows compared with normal
if baseline_count > 0:
velocity_ratio = current_count / baseline_count
else:
velocity_ratio = current_count * 10 # new topic bonus
# Recency weight: exponential decay
recency_weight = sum(
tweet.weight * exp(-lambda * (now - tweet.timestamp))
for tweet in current_window.tweets
)
# Engagement boost
engagement_score = (likes + retweets * 2 + replies * 3) / total_tweets
# Final score
score = velocity_ratio * recency_weight * (1 + log(engagement_score))
# Spam / bot filtering
if unique_users_ratio < 0.3: # too few unique users
score *= 0.1 # heavy penalty
return scoreTimeline Ranking
Modern Twitter/X does not rely purely on chronology. It uses ranking to estimate the probability of engagement and move more relevant tweets higher in the home timeline.
Ranking features
Tweet features
- Tweet age.
- Presence of media.
- Presence of links.
- Text length.
- Current engagement velocity.
- Author's average engagement rate.
User features
- Historical interactions with the author.
- Topic interests.
- Time-of-day activity patterns.
- Distance in the follow graph.
- Device type.
- Current session context.
Two-pass ranking
Pass 1: candidate selection. The system gathers roughly 1000 tweets from the home-timeline cache, from celebrity tweets, and from recovery blocks such as “In case you missed it.”
Pass 2: final ranking. The ranking model scores each candidate, and the top part of the list is shown to the user. Inference is usually kept within tens of milliseconds.
Search Architecture
Search lives in a separate path: new tweets first land in a realtime index and later compact into on-disk segments. On the query path, the system parses the request, searches shards in parallel, and merges the results afterward.
Search Pipeline
Switch between the indexing path and the user query path.
Indexing Flow
Document Intake
tweet and tokenization
Realtime Index
in-memory Lucene shards
Cold Index
on-disk segments
Query Flow
Query Parsing
terms and filters
Shard Fan-out
parallel search
Merge and Rank
recency and engagement
Data Model
The primary store keeps normalized entities, while the hot read path relies on denormalized Redis structures and auxiliary indexes to stay fast.
# Core tables
tweets {
tweet_id: UUID (Snowflake ID)
user_id: UUID
content: VARCHAR(280)
media_urls: JSON
created_at: TIMESTAMP
reply_to_tweet_id: UUID (nullable)
retweet_of_id: UUID (nullable)
quote_tweet_id: UUID (nullable)
like_count: INT
retweet_count: INT
reply_count: INT
}
users {
user_id: UUID
username: VARCHAR(15)
display_name: VARCHAR(50)
bio: VARCHAR(160)
follower_count: INT
following_count: INT
is_verified: BOOLEAN
is_celebrity: BOOLEAN # follower_count > 10K
created_at: TIMESTAMP
}
follows {
follower_id: UUID
followee_id: UUID
created_at: TIMESTAMP
PRIMARY KEY (follower_id, followee_id)
}
# Denormalized structures for reads
user_timelines (Redis Sorted Set)
Key: timeline:{user_id}
Score: tweet_timestamp
Member: tweet_id
# Tweets from very large accounts
celebrity_tweets (Redis Sorted Set)
Key: celebrity:{user_id}
Score: tweet_timestamp
Member: tweet_idSnowflake ID Generation
Twitter created Snowflake ID to generate unique, roughly time-sortable identifiers without a centralized coordinator.
# Snowflake ID structure (64-bit)
┌────────────────────────────────────────────────────────────────┐
│ 1 bit │ 41 bits timestamp │ 10 bits │ 12 bits │
│unused │ (milliseconds) │machine │ sequence │
│ │ since epoch │ ID │ number │
└────────────────────────────────────────────────────────────────┘
# Properties:
# - Roughly sortable by time
# - No central coordination required
# - 4096 IDs per millisecond per machine
# - Enough range for decades before overflow
# Example ID: 1605978261000000000
# Timestamp: 2020-11-21 12:31:01 UTC
# Machine: 42
# Sequence: 0
def generate_snowflake_id(machine_id, last_timestamp, sequence):
timestamp = current_time_ms() - TWITTER_EPOCH
if timestamp == last_timestamp:
sequence = (sequence + 1) & 0xFFF # 12 bits
if sequence == 0:
timestamp = wait_next_millis(last_timestamp)
else:
sequence = 0
id = (timestamp << 22) | (machine_id << 12) | sequence
return id, timestamp, sequenceHigh-Level Architecture
At the top level, the design separates publishing, home-timeline reads, search, and trends into different paths. The important part is not to force them through one universal chain, but to give each path its own cost profile, caches, and failure behavior.
High-Level Architecture
Select a flow to highlight the key components.
Edge and Routing
Clients
web and mobile apps
CDN
static assets and media
Load Balancer
traffic routing
API Gateway
auth and rate limits
Core Services
Tweet Service
tweet intake and writes
Timeline Service
home feed assembly
Search Service
user query path
Trending Service
stream processing
User Service
profiles and follow graph
Async Layer and Data
Message Queue
Kafka and async fan-out
Tweets DB
primary storage
Home Timeline Cache
Redis ZSETs
Search Index
Lucene and Elasticsearch
Trending Cache
Redis sorted sets
Graph DB
follow graph
Interview Tips
Key trade-offs
- Fanout-on-write vs fanout-on-read and why Twitter ends up hybrid.
- The cost of caching versus the cost of assembling on demand.
- Feed freshness versus response speed.
- Trend accuracy versus the cost of stream processing.
Common follow-up questions
- What do you do with an account that has 100M followers?
- How do you scale the fan-out workers without hours of backlog?
- How do you separate real trends from spam and bots?
- How would you layer “For You” personalization on top of the base feed?
Additional Resources
Related chapters
- System Design Interview: An Insider's Guide (short summary) - provides a classic framework for talking about the home timeline, tweet fan-out strategy, and the trade-offs between speed and cost.
- Chat System - covers adjacent patterns for long-lived connections, instant delivery, and online workloads under sustained pressure.
- Designing Data-Intensive Applications, 2nd Edition (short summary) - strengthens the foundations around stream processing, replication, consistency, and systems driven by large event volume.
- Event-Driven Architecture: Event Sourcing, CQRS, Saga - explains the event backbone behind asynchronous fan-out, background queues, and feed-service decomposition.
- Social Media Infrastructure View - extends the view to social-domain architecture across publishing, feeds, identity, media, and engagement signals.
- Acing the System Design Interview (short summary) - helps structure a Twitter/X interview answer around requirements, sizing, architecture, and the key trade-offs.
- Hacking the System Design Interview (short summary) - adds practical guidance for follow-up questions and defending your architecture during an interview.
- Frontend system design case study: Design Instagram Feed - shows the client-side view of a feed product: UX flow, rendering, and frontend behavior under load.
- System design case studies examples - helps compare Twitter/X with other common cases and see which architectural patterns repeat.
