Requirements
Functional Requirements:
Users shall be able to create and post a tweet with a maximum length of 140 characters.
Users shall be able to follow other users.
Users shall be able to unfollow other users.
Users shall be able to like tweets posted by other users.
The system shall display a home feed containing tweets from accounts the user follows.
The system shall show tweets in the home feed in chronological or ranked order, depending on product rules.
The system shall identify and display the top popular tweets in the home feed based on engagement metrics such as likes and follower count.
Users shall be able to refresh or reload the home feed to see newly posted tweets from followed users.
The system shall associate each tweet with its author and metadata such as timestamp and like count.
Non-Functional Requirements:
Low latency: timeline loads should feel near-instant, and sources describe feed systems targeting roughly sub-100 ms to a few hundred ms at high percentiles for reads.
Scalability: the system must handle millions of users, heavy read traffic, and traffic spikes during major events without large degradation.
High availability: home feed and profile reads should remain available even during partial failures because these are the most user-visible surfaces.
Reliability and durability: once a twit or like is acknowledged, the system should not lose it, so replication and durable storage are important.
Consistency model: eventual consistency is acceptable for feeds and top- rankings if updates appear within seconds, while follow/unfollow and write acknowledgment usually need stronger guarantees.
Throughput: the system must sustain very high write and fan-out rates for tweets, likes, and follow graph updates.
Security and abuse resistance: authentication, authorization, rate limiting, spam prevention, and protection from fake-like manipulation are required in any social platform.
Observability and maintainability: latency metrics, tracing, logs, and alerting are essential because fan-out and ranking pipelines fail in subtle ways.
These NFRs strongly influence architecture choices: feed systems usually rely on caching, distributed storage, and a hybrid push/pull timeline strategy, where normal users may use fan-out-on-write while celebrity accounts often use fan-out-on-read to avoid extreme write amplification.
For the “top popular tweets” requirement, teams commonly use streaming aggregation plus a ranking structure such as cached counters or sorted sets, because recomputing popularity from raw likes on every request would be too slow.
API Design
For API design, define the endpoints around the main write paths—post tweet, follow/unfollow, like/unlike—and the main read paths—get tweet, get user tweets, get home feed, and get top popular tweets. In system design, the point of this section is to make the request/response contracts explicit, because they drive the high-level architecture, storage, caching, and async processing choices later.
POST tweets Create a new tweet up to 140 characters.
GET /tweets/{tweetId} Fetch one tweet with metadata such as author, timestamp, and likes.
GET /users/{userId}/tweets Fetch tweets posted by a specific user.
POST /users/{userId}/follow Follow a user.
DELETE /users/{userId}/follow Unfollow a user.
POST /tweets/{tweetId}/like Like a tweet.
DELETE /tweets/{tweetId}/like Remove a like from a tweet.
GET /feed/home?cursor=...&limit=20 Get the home feed for the logged-in user with pagination.
GET /feed/top?k=10&cursor=... Get top popular tweets based on ranking score.
Request examples
For the write APIs, the request bodies can be small and simple because each action changes one core resource or relation. Typical payloads for tweet creation and interactions follow standard REST patterns used in Twitter-like system design examples.
POST /tweets
{
"authorId": "u123",
"text": "Hello world"
}
POST /tweets/{tweetId}/like
{
"userId": "u456"
}
POST /users/{userId}/follow
{
"followerId": "u456"
}
Read path
The main read path is the home timeline: the client calls GET /feed/home , the API gateway authenticates the user, the feed service gets precomputed tweet IDs from cache or timeline storage, then hydrates them with tweet and author data before returning the response. Many Twitter/news-feed designs use cursor pagination here because it scales better than offset pagination for fast-moving feeds.
A typical response can return tweet data plus a nextCursor for the next page. This contract also makes room for merging normal followed-user tweets with a separate top- or ranked feed source.
GET /feed/home?cursor=abc123&limit=20
{
"tweets": [
{
"tweetId": "t1",
"authorId": "u10",
"text": "New post",
"createdAt": "2026-05-12T11:00:00Z",
"likeCount": 120
}
],
"nextCursor": "abc124"
}
Write path
The main write path for POST /tweets is usually: client request, auth and rate limiting, tweet stored in the tweet database, then an async event is pushed to a queue so fan-out workers can update followers’ home feeds. This separation keeps tweet creation fast for the user while feed propagation happens in the background.
The same idea applies to likes and follows: the API acknowledges the write quickly, stores the relation or counter change, and then updates caches, counters, or ranking services asynchronously when needed. That is especially important for top- popular tweets, because popularity scores are usually computed incrementally rather than by rescanning all tweets on every request.
High-Level Design
Here’s the overall architecture for a Twitter-like system, with the main components split into read, write, storage, and ranking paths. The design is typically built around an API layer, services for tweets/follows/likes/feed, persistent databases, a queue for async propagation, and a ranking pipeline for top- popular tweets.
Main components
• Client apps send requests for posting tweets, following, liking, and loading feeds.
• API Gateway / Load Balancer handles routing, authentication, rate limiting, and request distribution.
• Auth Service validates users and tokens.
• User Service manages user profiles and follow relationships.
• Tweet Service stores tweet content and metadata.
• Like Service records likes and updates engagement counters.
• Feed Service assembles the home feed and returns tweets to the client.
• Event Queue / Kafka decouples write requests from downstream feed updates.
• Fan-out Workers consume tweet events and update followers’ home timelines asynchronously.
• Ranking Service computes top- popular tweets using likes and follower-related signals.
• Datastores include a User DB, Follow Graph DB, Tweet DB, Like Counter/Cache, and Home Timeline Cache.
End-to-end flow
For tweet creation, the client posts to the API gateway, the Tweet Service writes the tweet to durable storage, and an event is published to the queue so fan-out workers can update follower timelines later. This keeps the write path fast while shifting expensive feed distribution to background workers.
For reading the home feed, the Feed Service fetches precomputed tweet IDs from the Home Timeline Cache, hydrates them with tweet data from the Tweet DB, and returns the result to the client. For the top- popular feed, the Feed Service or Ranking Service uses like counters and follower signals to produce ranked results efficiently.
Why this split works
This architecture balances low-latency reads with scalable writes, which is the core challenge in news-feed systems. Fan-out-on-write is efficient for normal users, while ranking and cached timelines avoid expensive recomputation on every request.
The block diagram above shows the system as a practical interview-style design: a synchronous request path for user actions, an asynchronous propagation path for feeds, and a separate ranking path for popular content.
Detailed Component Design
Feed Service
How it works: The Feed Service handles GET /feed/home and GET /feed/top . It fetches tweet IDs from the Home Timeline Cache for the user’s followed accounts, hydrates them by joining with Tweet DB and User DB for metadata, applies sorting (chronological or relevance), and returns paginated results. For top-, it pulls from the Ranking Service.
Data structures: Timeline cache stores sorted lists of tweet IDs per user (e.g., Redis sorted sets with score = timestamp). Hydration uses batch lookups to avoid N+1 queries.
Scaling: Stateless service sharded across nodes. Cache hit ratio >95% keeps latency <100ms. Use read replicas for DB joins. Capacity: for 1M DAU with 20 tweets/feed, ~20M reads/day; scale horizontally with consistent hashing on userId.
Tradeoffs: Cache hit vs. freshness—evict stale timelines after 1–5 minutes. Fan-in (read-time assembly) for celebrities vs. precomputed fan-out for normal users.
Fan-out Workers
How it works: These process events from Kafka/queue after tweet/like/follow writes. For a new tweet, read the author’s followers (capped at 10K for efficiency), append the tweet ID to each follower’s timeline cache (Redis list or sorted set), and expire old entries. Likes update counters in a separate store.
Data structures: Follow graph as adjacency list in graph DB (Cassandra/JanusGraph). Timeline as Redis ZSET: ZADD user:timeline tweetId timestamp.
Scaling: Horizontal workers with Kafka partitions = worker count. Batch updates (append 100 tweets at once). Capacity: celebrity tweet with 1M followers = 1M writes; use follower bucketing (update top 1K fans immediately, rest on read).
Tradeoffs: Fan-out-on-write (fast reads, high write amp) vs. fan-out-on-read (low writes, slow celebrity reads). Use hybrid: fan-out for <10K followers. Durability via queue acks.
Ranking Service
How it works: Computes top- tweets using score = likes * log(followers_of_author) + recency decay. Streaming counters (Redis incr) track likes; graph DB provides follower counts. Run periodic jobs (every 30s) to rescore and cache top 100–1000 in a global sorted set. Feed Service reads from this cache.
Data structures: Like counters in Redis (TWEET:{id}:likes). Global leaderboard as Redis ZSET with composite score. Decay: score *= exp(-hours_since_post / 24). Top-K via ZREVRANGE 0 K-1.
Scaling: Stateless scorer with sharded counters. Capacity: 1B likes/day → ~10K ops/sec; use approximate counters (HyperLogLog) for scale. Cache TTL 60s.
Tradeoffs: Exact vs. approximate ranking (Bloom filters for dedup). Real-time (stream process) vs. batch (slower but cheaper). Gaming resistance via rate limits and decay.
Capacity notes
Assume 1M DAU, 100 tweets/user/day, 10% like rate: ~100M tweets/day, 10M likes/day, 1B follow edges. Feed reads: 20M/day. Services scale to 10K RPS with 10–20 nodes each.
These components handle the core bottlenecks: read amplification (Feed), write fan-out (Workers), and dynamic scoring (Ranking).