Design Twitter / News Feed
hardA social feed system serves a per-user, recent-first list of posts from accounts the user follows. Twitter / X is canonical; Facebook, Instagram, LinkedIn, TikTok share the architecture. Two forces dominate: writes are easy (a few tweets per user per day) but reads explode through follower fanout, and the feed must render in under 200 ms on every app open.
Key Concepts
High-level design
Write path: client → API → tweet service (write to durable store) → Kafka FanoutEvent → fanout workers → timeline cache.
Read path: client → API → timeline cache (precomputed) + celebrity outbox pulls (merged) → ranker → response.
Search: tweets → Kafka → Elasticsearch indexer.
Media: tweets with photos/videos → S3 + CDN.
Async pipelines: notifications, analytics, recommendation training.
Components
- Tweet service (write path; sharded by tweet_id).
- Social graph service (followers, following).
- Fanout workers (Kafka consumers).
- Timeline cache (Redis sorted set per user, capped at 800 entries).
- Durable timeline store (Cassandra wide row) for cold/pagination.
- Ranker (TF Serving / Triton).
- Search indexer + Elasticsearch.
- Media service (S3 + CDN, transcoding pipeline).
- Notification service.
- Anti-abuse service (spam, hate, NSFW).
Fanout strategies in depth
Push (fanout-on-write): one write becomes N timeline appends. Read latency: one Redis call. Write cost: O(followers). Bad for celebrities.
Pull (fanout-on-read): no fanout at write. Read fetches follow list, pulls recent tweets from each, merges. Write cheap; read O(following) — bad UX at scale.
Hybrid: push for follower count < threshold (e.g., 1M); pull for celebrities. Read = precomputed + small set of pulls.
Pull cap: only pull from top-K celebrities the user follows to bound read cost.
Active-user push: only fan out to active users (logged in recently); inactive users get pull at next login. Cuts fanout cost dramatically.
Ranking pipeline
Candidate generation: pull from precomputed timeline + celebrity outboxes + topical sources (hashtag follows, recommendations).
Feature fetch: online feature store (Redis/Feast) with last-minute features (recency, recent engagement).
Model scoring: GBDT for cost-efficiency or DNN for richer features.
Re-rank: diversity rules (no two consecutive items from same source), freshness boost, business rules (ads).
Logging: impressions + engagement signals → Kafka → training data lake.
Trade-offs
Push: fast reads, expensive writes for high-follower users.
Pull: cheap writes, slow reads.
Hybrid: best of both, more complex.
Chronological vs ranked: chronological is simpler and what users say they want; ranked actually drives engagement.
Timeline cache cap: 800 entries works for the open-feed use case; pagination falls back to durable store.
Strong consistency on social graph: hard. Most systems are eventually consistent for follows — accept that a new follow takes seconds to show in the feed.
Real-world references
- Twitter: 'Timeline' system uses hybrid push/pull; Manhattan (KV) for tweets; Redis for timelines.
- Instagram: Cassandra timelines + Redis cache, ranked feed.
- Facebook: TAO (graph) + dense ranking infrastructure.
- TikTok: For-You page is candidate generation + heavy ML reranking, less fanout-driven.
- LinkedIn: feed system Volur, GraphQL gateway.