Security Notes
System Design

Design Facebook News Feed

4 min read 7 sections

DifficultyMedium | HelloInterview: problem breakdown


Problem Statement

Design a news feed system where users can publish posts and see a personalized, ranked feed of posts from people they follow. Think Facebook, Instagram, Twitter timeline.

๐Ÿ“–

Real-world: The feed is the home of the "fan-out on write vs fan-out on read" tradeoff, and the canonical war story is Twitter's celebrity problem: precomputing each user's timeline on write (push) is great for normal users but explodes for accounts with tens of millions of followers โ€” when Lady Gaga tweets, you can't synchronously write to 80M inboxes. Twitter's real architecture became a hybrid: push for most users, but pull (compute at read time) for celebrity posts, merged in when you load your feed. The early Twitter that couldn't handle this gave us the legendary "fail whale." Security/integrity angle for this audience: the modern feed is also a ranking and trust-and-safety battleground โ€” spam, coordinated inauthentic behavior, and misinformation are filtered in the same pipeline that ranks for engagement, so "the feed" is as much an abuse-detection system as a distributed-systems one.


Requirements

Functional

  • Users can create posts (text, images, links)
  • User sees a ranked feed of posts from people/pages they follow
  • Feed is paginated
  • Feed is somewhat real-time (new posts appear within minutes)

Non-Functional

  • 500M daily active users
  • Average user follows 300 others
  • Peak: 5M posts/s (like spikes during events)
  • Feed read latency: < 200ms P99
  • Eventual consistency is acceptable (slight staleness is OK)

Scale Estimation

  • Write: 500M users ร— 10 posts/day / 86400 = 58k posts/s average
  • Read: 500M users ร— 10 feed loads/day / 86400 = 58k feed reads/s average
  • Fan-out: each post written โ†’ pushed to followers' feeds. Average 300 followers = 17M feed writes/s (!)
  • Celebrity problem: Justin Bieber with 100M followers = 100M feed writes per post (!)

Core Design

The fundamental choice: fan-out on write vs fan-out on read.

Fan-Out on Write (Push Model)

User posts โ†’ Post Service โ†’ Fan-out Worker Queue
                                     โ†“
                        For each follower: write post_id to their feed cache
                                     โ†“
                               Feed Cache (Redis)
                                     โ†‘
                          User loads feed โ†’ read from cache
Pro

feed reads are fast (pre-computed, just read from cache)

Con

celebrity posts trigger massive write fan-out (100M writes for 1 post)

Con

storage cost (storing N copies of every post)

Fan-Out on Read (Pull Model)

User loads feed โ†’ Feed Service โ†’ fetch following list
                                      โ†“
                          Query N "post" tables for each followee
                                      โ†“
                              Merge + rank โ†’ return
Pro

writes are cheap (post once, no fan-out)

Con

reads are expensive (N DB queries per feed load โ€” can't scale)

Hybrid Model (Production Reality)

Regular users (< 1000 followers):  fan-out on write โ†’ pre-populated feed cache
Celebrity users (> 1M followers):  fan-out on read โ†’ fetched and merged at read time

At feed load time:

  1. Read pre-computed feed IDs from Redis (regular followees)
  2. Fetch last N posts from celebrity followees directly
  3. Merge + rank all posts
  4. Return paginated result

Architecture

                    Post Service (write)
                         |
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚                         โ”‚
        Fan-out Queue              Post DB (Cassandra/DynamoDB)
              โ”‚                         โ”‚
         Fan-out Workers           Object Store (S3 for media)
              โ”‚
        Feed Cache (Redis)
        {user_id: [post_id, post_id, ...]}

                    Feed Service (read)
                         |
                 Check Redis Cache
                 + Merge celebrity posts
                 + Hydrate post data (Post Service)
                 + Ranking (ML model)
                 โ†’ Response

Data Models

Posts DB (Cassandra โ€” wide-column, excellent for time-series queries):

posts_by_author(
  author_id  UUID,
  created_at TIMESTAMP,
  post_id    UUID,
  content    TEXT,
  media_urls LIST<TEXT>,
  like_count INT,
  ...
  PRIMARY KEY (author_id, created_at DESC)
)

Feed Cache (Redis):

Key:   feed:{user_id}
Value: sorted set of post_ids ordered by rank_score
TTL:   24 hours (rebuild on miss)

Ranking

Simple scoring: score = base_time_decay + engagement_boost + affinity_score

  • Can be a lightweight ML model or simple formula
  • Applied during fan-out write OR at read time (trade latency for freshness)

Key Design Decisions

DecisionChoiceReason
Fan-outHybrid (write for normal, read for celebs)Balances write load vs read latency
Post storageCassandraTime-series read pattern per author; high write throughput
Feed storageRedis sorted setO(log N) insert, O(1) range read, TTL-based GC
MediaS3 + CDNBlob storage + edge caching
ConsistencyEventualSocial feed staleness is acceptable

Security Considerations

ThreatMitigation
Privacy / visibility controlFeed worker checks privacy settings before fan-out (public vs friends-only posts)
Feed poisoningValidate post content at write time; scan for malware URLs
Mass DM / spam accountRate limit post creation; ML spam classifier
Account takeover โ†’ defacement2FA on accounts; post velocity alerts for suspicious activity
Data exfiltration via feed APIPaginate responses; no bulk export API; authentication required
SSRF via link previewPreview link metadata in sandboxed environment; block internal IPs
Stored XSS via post contentSanitize HTML/markdown at write time; Content-Security-Policy on frontend

Interview Tips

The fan-out dilemma is the crux

spend time on push vs pull vs hybrid.

Celebrity problem

(Justin Bieber problem) is the famous gotcha โ€” you must handle it.

Don't skip ranking

even a simple formula shows you understand feed relevance is not just chronological.

Redis sorted set

is the canonical answer for feed cache storage.

Eventual consistency is fine here

say it explicitly and explain why (user won't notice 30-second staleness in a social feed).