Posts fanning out into user timelines

Design a news feed

Fan-out on write vs read, celebrity users, and hybrid timelines — with the arithmetic that turns a 50-million-follower post into the whole design problem.

At a glance

A user opens the app and sees recent posts from people they follow. Writes are relatively rare; reads are constant. The hard part is fan-out cost — especially when one user has millions of followers.

Analogy diagram: push newspaper delivery versus pull newsstand reads.
Morning paper routes: push to every porch vs pull at the newsstand.
01Requirements

Follow, post, home feed ranked.

02Push vs pull

Write-time fan-out vs read-time merge.

03Hybrid

Push normals · pull celebrities.

04Ranking

Candidates first, rank second.

05Celebrity problem

Hot keys and mega fan-out.

06Interview flow

Clarify → HLD → hybrid deep dive.

Takeaway

This is a fan-out cost problem under a skewed follower graph. Compare push vs pull, land on hybrid — push for normal users, pull for celebrities — then deep-dive the celebrity hot key.

Whiteboard order

Draw in this order so push vs pull is visible before you invent ranking ML.

  1. First — product + NFRs: follow, post, home feed; read-heavy; freshness SLA; celebrity skew called out.
  2. Second — capacity numbers: DAU, posts/day, avg follows, feed opens/day, celebrity threshold. Circle the fan-out blow-up.
  3. Third — two fan-out sketches: push on left, pull on right, then hybrid arrow. Entities: posts, follows, timeline.
  4. Then deep dives: async workers, ranking as a separate stage, hot-key cache, pagination cursors.
Takeaway

Requirements → capacity → push/pull diagram → hybrid. Ranking is a stage after candidates are gathered, not the opening act.

Requirements

Get the product shape before arguing Cassandra vs Redis.

Functional

  • Users follow other users (asymmetric — not mutual like Facebook friends).
  • Users create posts (text, image, video references).
  • Home feed shows posts from followed users, ranked by recency or relevance.
  • Optional later: likes, comments, notifications, ads, "people you may know."

Non-functional

  • Reads ≫ writes — optimize the feed read path.
  • Latency — first page of feed should feel instant (cache-friendly).
  • Freshness — eventual consistency OK for many feeds; state your SLA.
  • Skew — follower counts follow a power law (celebrities break naive designs).
Takeaway

Lock follow + post + home feed. Reads dominate, first page must feel instant, eventual consistency is fine for a few seconds, and follower counts are power-law — that skew drives the architecture.

Capacity math worked example

Do this arithmetic on the board before arguing Cassandra. Numbers make hybrid inevitable.

  • Assumptions: 100M DAU, each opens feed 10×/day, each follows 200 people, 1 post/user/day on average, 0.1% of users are celebrities with ≥1M followers.
  • Feed reads: 100M × 10 / 86,400 ≈ ~12k QPS average feed opens. Peak 5–10× → 60–120k QPS. Cache the first page.
  • Posts (writes): 100M × 1 / 86,400 ≈ ~1.2k post QPS average. Manageable — the cost is fan-out, not the insert.
  • Pure push blow-up: one celebrity with 50M followers → 50M timeline writes per post. Even at 100k writes/sec that's ~8 minutes of fan-out for one trailer drop — and most followers are inactive.
  • Normal push: user with 200 followers → 200 timeline writes. Async workers finish in milliseconds. Fine.
  • Hybrid savings: push for ~99.9% of users; pull ~100k celebrities at read time into the merge. Celebrity post write cost stays O(1).
Napkin math: feed reads at 12k QPS, post writes at 1.2k QPS, and a circled 50 million write fan-out blow-up for a single celebrity post.
~12k feed QPS · ~1.2k post QPS · one celebrity post = 50M writes.

This napkin is what turns hybrid from a memorized answer into a derived one. The trade-off is visible in the numbers: pure pull would merge 200 followees' recent posts on every feed open at 12k QPS — doable with good indexes and cache, but precomputed timelines are simply snappier for normal users. Worth anticipating next: inactive followers (skip fan-out until next login) and hot keys when everyone pulls the same celebrity's recent posts.

Takeaway

The celebrity fan-out product — followers × posts — is the one number that makes hybrid inevitable instead of a buzzword.

Push vs pull fan-out

This is the heart of the interview. Draw both, then land on hybrid.

Poster fans out via push to follower timelines versus pull timeline merge at read time.
Push = fan-out on write · Pull = fan-out on read · Hybrid mixes both.
  • Fan-out on write (push) — when a post is created, write a pointer into each follower's timeline store. Fast reads; expensive celebrity posts.
  • Fan-out on read (pull) — on feed open, fetch recent posts from followed users and merge. Cheap writes; heavier reads.
  • Hybrid — push for normal users; pull celebrity posts into the merge at read time.

Tradeoff table in words: Push wins when follower counts are small and feeds must be snappy. Pull wins when graph is sparse or writers are rare celebrities. Real products almost always hybridize.

Why you must draw both before picking: push moves cost to write time, pull moves it to read time. Neither is universally better — the follower distribution decides. Pitch push alone and it collapses the moment one account gets millions of followers. Pitch pull alone and normal users with a few hundred follows pay an unnecessary read cost on every feed open. Land on hybrid with a numeric threshold (e.g. 10k followers) so the rule is testable.

Takeaway

Never pick only push or only pull without naming the celebrity problem. Hybrid, with an explicit follower threshold, is the default answer.

Hybrid design (the default pick)

There's no perfect feed — only the right fan-out for your write and read mix.

Most designs land on hybrid fan-out. Walk it as a sequence so the interviewer can follow.

  1. Define a follower threshold (e.g. 10k) — above = celebrity.
  2. Normal user posts → async fan-out on write to all followers' timeline caches.
  3. Celebrity posts → write to their profile / posts store only; skip mass fan-out.
  4. On feed read: fetch precomputed timeline + recent posts from followed celebs + merge + rank.
  5. Return first page; use cursor pagination for the rest.
Hybrid news feed high-level design: write path from client through API, posts store, queue, fan-out workers to timeline, with celebrity posts skipping mass fan-out; read path merges timeline ZSET and celebrity recent posts before ranking and paginating.
Write path pushes for normal users and skips fan-out for celebs; read path merges both before ranking.
Three tables: posts with post_id and author_id index, follows with composite follower/followee key, and timeline with user_id shard key; celebrity posts skip the timeline table.
posts · follows · timeline — celebrity posts never get a timeline row.

API sketch — enough to draw three boxes and move on:

  • POST /posts — body: content, media_refs. Writes to posts store, enqueues fan-out job (skipped for celebrity author_id), returns post_id immediately.
  • POST /follow — body: followee_id. Writes a row to follows; no timeline backfill needed since old posts aren't retro-fanned-out.
  • GET /feed?cursor= — returns ranked page + next cursor (post_id + timestamp), reading from timeline ZSET merged with celebrity pulls.

Post creation should return fast. Fan-out workers consume a queue: look up followers, batch-write timeline rows, handle retries with idempotency keys.

Why async fan-out is non-negotiable: a user with 5k followers cannot wait for 5k synchronous writes on the publish request. Return the post ID immediately; workers churn the timeline store. Trade-off: followers may see the post a second or two later — usually acceptable under your freshness NFR. Worth anticipating: idempotent consumers (retry must not duplicate timeline rows), partial fan-out failure, and what happens when someone unfollows mid-fan-out (orphaned row is fine; next read filters).

Takeaway

Threshold + async workers + timeline table + celebrity pull at read — those four pieces are the whole hybrid design.

Ranking basics

Recency-only is MVP. Production feeds add ranking — engagement signals, affinity, diversity. In interviews, mention ranking as a separate stage after candidate generation.

  • Candidate generation — gather ~hundreds of post IDs from timeline + celebrity pulls.
  • Ranking — score by recency, affinity, engagement; apply diversity filters.
  • Pagination — cursor-based (post_id + timestamp) — stable under new inserts.
  • Cache the first page per active user — highest QPS path.
  • Rank in app tier or dedicated ranking service — not in a giant DB join.
  • Phase two: ML model, ads insertion, "see first" preferences.
Ranking pipeline: candidate generation gathering timeline and celebrity pulls, then ranking by recency and engagement, then pagination and caching the first feed page.
Candidate gen → rank → paginate/cache — correctness in stage one, quality in stage two.
Takeaway

Candidates first, rank second — say it in that order. Recency plus a simple score is enough for MVP; don't invent an ML ranker unless asked.

The celebrity problem

Follower graphs are power-law. One superstar-tier account can destroy a naive push design and heat up a single partition on pull.

  • Push blow-up — writing tens of millions of timeline rows per celebrity post is slow, costly, and often unnecessary (many followers are inactive).
  • Hot keys on pull — everyone reading a celeb's recent posts hits the same author partition / cache key.
  • Mitigations — hybrid threshold; dedicated celebrity post cache; replicate hot keys; rate-limit post creation for spam.
  • Inactive followers — skip fan-out to dormant users; materialize on next login (lazy fan-out).
Side by side comparison: pure push causes 50 million timeline writes for one celebrity post, versus hybrid design keeping writes O(1) with pull-at-read merge and a hot-key cache.
Left: naive push blow-up. Right: O(1) write, pull-at-read merge, hot-key cache.

Volunteering this early matters because the celebrity problem is the natural deep dive here. Pure push dies on write amplification; pure pull dies when millions of feed opens hammer one author partition. Hybrid plus a dedicated celebrity recent-post cache is the standard recovery. Lazy fan-out to inactive users is a nice-to-have on top — don't spend the whole clock on it.

Takeaway

Volunteer the celebrity problem before being asked. Hybrid plus a hot-key cache on the celebrity's recent posts is the fix.

Caching and scale checklist

Feeds are a caching problem wearing a social-network costume.

  • Shard timeline storage by user_id (the reader).
  • Async fan-out workers — post creation returns fast; fan-out happens in queue.
  • Cache hot timelines / first pages for active users in Redis.
  • Cache celebrity recent-post lists separately.
  • Media in object storage (S3); feed stores references only.
  • Rate-limit post creation; detect spam patterns.
  • Idempotent fan-out consumers — retries must not duplicate timeline rows forever.

Failure modes worth naming before asked: Queue lag — if the fan-out queue backs up under a viral spike, normal users see stale feeds for minutes; alert on consumer lag, not just error rate. Partial fan-out — a worker crashes after writing 40k of 200k rows; retry the whole job with an idempotency key (dedup on (post_id, user_id) or an upsert) rather than trusting "it probably finished." Cache stampede — a celebrity's hot-key cache entry expires and thousands of concurrent reads all miss at once and hammer the same author partition; use request coalescing or staggered TTLs. Unfollow mid-fan-out — a user unfollows while their old timeline rows are still being written; treat the orphaned row as harmless and filter it at read time rather than trying to cancel in-flight writes.

Takeaway

Shard by reader, cache the first page, fan out asynchronously, keep media out of band. Design for the skew, not the average.

Interview flow (45 minutes)

Use this as your route so you don't rabbit-hole into ranking ML.

  1. ~5 min — requirements + NFRs (read-heavy, skew) + rough capacity.
  2. ~3 min — entities: users, follows, posts, timeline.
  3. ~5 min — API: create post, follow, get feed (cursor).
  4. ~12 min — HLD: push vs pull diagram → land on hybrid.
  5. ~10 min — deep dives: celebrity, caching, ranking stage, pagination.
  6. ~5 min — wrap-up: MVP sentence + 10× sentence.

Cost and performance levers

Write amplification is a dollar problem, not just a latency one. Every timeline row is a write unit you pay for — 10M followers × 1 post is 10M billed writes on most managed stores, and a handful of celebrity posts a day can dwarf the write cost of every normal user's post combined. The hybrid split isn't only about tail latency; it's the difference between a linear cost curve and one with 50M-write spikes. Layer in lazy fan-out for inactive users: don't write a timeline row for a follower who hasn't opened the app in 30 days — materialize their timeline on next login instead. For a network where a meaningful fraction of accounts are dormant, this alone can cut fan-out write volume substantially without touching the celebrity path at all.

Fan-out decision board

Celebrity problem numbers

1M followers × write fan-out = 1M cache updates per post — too slow/expensive. Exception path: don't precompute; merge celebrity posts at read time from a separate store.

Failure modes to mention

Generic "DB down, add retries" doesn't land in a feed interview. Name the feed-specific ones: fan-out queue backlog during a viral moment (mitigation: autoscale workers, shed load by deprioritizing lazy fan-out first, alert on consumer lag); celebrity read hot key when a trending post's author partition gets hammered (mitigation: dedicated hot-key cache, request coalescing); timeline store partial write from a crashed worker (mitigation: idempotent upserts keyed on (post_id, user_id), not blind retries); and ranking service timeout on the read path (mitigation: degrade to recency-only rather than fail the whole feed request).

Interview Q&A by level

Practice saying these out loud for news feed design. Interviewers grade clarity and judgment more than buzzwords.

Architecture by level

Three progressive sketches — beginner spine, mid optimizations, pro production depth. Use the matching diagram in the interview; say the tradeoff out loud.

Beginner news feed: fan-out on write versus fan-out on read.
Beginner architecture

Pros: Naming push vs pull with a diagram proves you understand the core cost model. Cons: Pure push explodes on celebrities; pure pull makes every feed open a merge — neither alone is the production answer.

Mid news feed: hybrid push for normal users and pull for celebrities.
Mid architecture

Pros: Hybrid is derived from napkin math (50M fan-out) — push normals, pull celebs keeps write amp and read latency balanced. Cons: Thresholding "who is a celebrity" and hot keys on celeb recent-posts need explicit handling or you recreate the blow-up on read.

Pro news feed: ranker, timeline cache, and cold storage.
Pro architecture

Pros: Separate candidate generation from ranking; timeline cache + cold storage match real feed stacks. Cons: Ranking ML and storage topology can swallow the hour — staff depth should pick fan-out math + hot keys, not every subsystem.

Poster fans out via push to follower timelines versus pull timeline merge at read time.
Redraw this from memory: push on the left, pull on the right.
Side by side comparison: pure push causes 50 million timeline writes for one celebrity post, versus hybrid design keeping writes O(1) with pull-at-read merge and a hot-key cache.
Redraw this from memory: the blow-up on the left is exactly what hybrid avoids.
Compact interview sketch: push normal posts to timeline, pull celebrity posts, merge both at read, rank, and return the feed page.
Redraw this from memory: one threshold, two paths, one merge — the whole answer in a single sketch.
Interview takeaway

Match depth to the bar: define → trade off → operate. Don't dump principal answers in an entry-level screen — but at every level, be able to redraw the push/pull/hybrid sketch from memory without hesitating. Full rubric: Interview bars by level.

← Lattice