shreyansh

HLD Playground · Case 03 · Advanced · 15 min

Twitter Timeline

Home (ranked, hybrid fan-out) + user (pull, CDN-cacheable) at 500M tweets/day. Core trick — dynamic celebrity thresholds + early-rank at ingest, merged at read time.

Write → merge

Push for most, pull for the famous

Toggle Normal ↔ Celebrity, then hit World-Cup final in Traffic. Two packets ride step 2 (one per branch); step 5 storms the workers and the metrics flip to the playbook.

1 · Tweet accepted fastIngest owns the p99: auth, validate, dedup by client mutation-id, persist. Never waits for media…
1/5

1 · Tweet accepted fast

Ingest owns the p99: auth, validate, dedup by client mutation-id, persist. Never waits for media transcode — renders progressively from blurhash.

Author type
Push path: Kafka → workers → followers' zsets.
Traffic
Hybrid steady state, lag < 5s.
Tweet writes avg / peak
5.8k / 23.1k
Fan-out (pure push)
~1.2M/s
forcing function for hybrid
Home reads avg
~23.1k/s
Home-cache RAM
~4.0 TB
80M cached × 50KB, LRU 7d
Post→home visibility
< 5s p50
celebrity pull < 30s staleness

Test yourself

1. Push or pull?

Bounded writes + fast merged reads. Threshold on follower count, auto-lowered under lag.

2. Why store only ids in feed cache?

Bodies hydrate via parallel MGET from post-cache/Cassandra.

3. Why never OFFSET?

Cursor on (score,id) is stable across inserts; offset duplicates/shifts.

4. What breaks first at 10×?

Playbook: lower thresholds, lag-autoscale, shed ads/WTF mixing first.
Drag nodes · scroll page normally · add ?elk to URL for auto-layout

10× event

World-Cup-final playbook

First bottleneck: fan-out worker lag during global events. Response — pre-lower thresholds (viral mid-size accounts get promoted to pull within minutes), autoscale workers on lag not CPU, shed WTF/ads mixing first (timelines stay correct, just less monetised), serve stale-while-revalidate past 30s lag. Next: home-zset RAM (800→400 cap, 7d→3d TTL for dormant) and reverse-edge reads (precomputed follower-shard snapshots).

Two systems, not one

Home timeline ≠ user timeline

Home timelineUser timeline
QueryBest of my graph (ranked, mixed)Everything by author X (chronological)
Fan-outHybrid push + celebrity pullNone — pure pull
CachePer-viewer Redis zset (private)Per-author head-cache + CDN (public)
CostViewer × sourcesAuthor × readers (CDN absorbs)

Say it: "user timeline is a cacheable archive; home timeline is a per-viewer computation — different SLOs, different stores." Deletes tombstone then scrub (~1 min) + purge CDN keys. Media never blocks accept: presigned direct upload, async transcode, blurhash placeholder first.

Say it in the room

Interview one-liners

  • Q: News Feed vs Twitter? / A: Same hybrid core + dynamic thresholds, early-rank, split home/user timelines.
  • Q: What breaks first at the final? / A: Fan-out lag — lower thresholds, lag-scale, shed ads/WTF.
  • Q: Why doesn't post wait for video? / A: Metadata persists + enqueues; media renders progressively.

Full write-up: Twitter Timeline case note · Prerequisite: News Feed case · Theory: Stream Processing, Cache Patterns · ← Back to all playgrounds · Pro unlocks News Feed, WhatsApp, YouTube + mock-interview mode.