# Content Feed System Low-Level Design

Source: https://www.techinterview.org/post/3233467330/lld-content-feed/
Updated: 2026-04-18 · techinterview.org

## Requirements

  - Generate a personalized feed of posts ranked by relevance/recency for each user

  - Supports follow relationships: see posts from users you follow

  - 500M users, 10M DAU, 100K new posts/minute

  - Feed load time <200ms; new posts appear in feed within 5 seconds

  - Mixed content: posts, images, videos, reposts

## Two Approaches: Fan-out on Write vs Fan-out on Read

**Fan-out on Write (push model)**: when a user publishes a post, immediately write it to the feed of all followers. Feed reads are fast (pre-built). Write amplification: if a user has 1M followers, 1 post = 1M feed writes. Good for users with few followers. Bad for celebrities (Justin Bieber problem).

**Fan-out on Read (pull model)**: when a user opens their feed, fetch recent posts from each followee and merge/rank them in real time. No write amplification. Feed generation is slow (O(followees) fetches per request). Good for power users with many followees.

**Hybrid (recommended)**: fan-out on write for normal users ( 10K followers). On feed load: merge pre-built feed (from write fan-out) + real-time fetch of recent celebrity posts.

## Data Model


```
Post(post_id UUID, author_id, content TEXT, media_urls[], post_type ENUM(TEXT,IMAGE,VIDEO,REPOST),
     repost_of UUID, created_at, like_count, comment_count, share_count)

Follow(follower_id, followee_id, created_at)
-- Index: (follower_id, created_at DESC) for "who I follow"
-- Index: (followee_id, follower_count) for follower count

FeedItem(user_id, post_id, score FLOAT, post_created_at, source ENUM(FOLLOW,RECOMMEND))
-- Stored in Redis sorted set: key=feed:{user_id}, member=post_id, score=ranking_score
```


## Feed Generation Service


```
On new post published by user U:
1. Publish to Kafka topic: new_posts
2. Fan-out workers consume from Kafka:
   a. Fetch follower IDs of U (from Follow table, paginated)
   b. For each follower F (if follower count of U <= 10K):
      ZADD feed:{F} {score} {post_id}
      ZREMRANGEBYRANK feed:{F} 0 -501  # keep top 500 only
3. Score = recency_score + engagement_score + personalization_score
```

The feed sorted set in Redis stores post_ids ordered by score. On feed read, ZREVRANGE feed:{user_id} 0 49 fetches the top-50 post_ids in O(log n + k). Then a batch DB lookup fetches post content for those IDs.

## Ranking Score


```
score = 0.4 * recency + 0.3 * engagement_velocity + 0.2 * relationship_weight + 0.1 * content_type_pref

recency = 1 / (1 + hours_since_post)          # decays over time
engagement_velocity = (likes + comments*2 + shares*3) / hours_since_post
relationship_weight = close_friend ? 1.5 : 1.0  # based on interaction history
content_type_pref = user_affinity_for_content_type  # from ML model
```


## Pagination and Cursor

Cursor-based pagination on the feed: the client sends last_seen_score on each request. The server fetches items with score < last_seen_score. This avoids the "shifting page" problem (offset pagination breaks when new items are inserted). Store cursor in the client; the server is stateless.

## New Post Delivery (5s SLA)

Fan-out workers process Kafka messages in near-real-time. For a user with 100K followers: fan-out = 100K ZADD operations. At 1ms per Redis operation, this takes ~100 seconds sequentially. Solution: parallel fan-out workers, each handling a shard of followers. With 100 parallel workers, 100K followers → 1K per worker → ~1 second total. Kafka partition by user_id for ordering; fan-out workers scale horizontally.

## Key Design Decisions

  - Hybrid fan-out: write for normal users, read for celebrities — eliminates write amplification spikes

  - Redis sorted set for feed — O(log n) insert, O(log n + k) range read, automatic score-based ranking

  - Kafka fan-out workers — async, scalable, fan-out doesn't block the post API

  - Cursor pagination — correct behavior for real-time feeds with frequent inserts

  - Score-based ranking — decoupled from storage; score can be recomputed by a re-ranking job

Meta system design is the canonical news feed interview topic. See common questions for [Meta interview: news feed and content ranking system design](https://www.techinterview.org/post/3233460272/meta-interview-guide-2026-facebook-instagram-whatsapp-engineering/).

Twitter system design covers feed generation and ranking. Review patterns for [Twitter interview: content feed and timeline system design](https://www.techinterview.org/post/3233460305/twitter-x-interview-guide-2026-timeline-algorithms-real-time-search-and-content-at-scale/).

Snap system design covers content feeds and story delivery. See design patterns for [Snap interview: content feed and story system design](https://www.techinterview.org/post/3233459923/snap-interview/).

See also: [Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence](https://www.techinterview.org/post/3233460274/netflix-interview-guide-2026-streaming-architecture-recommendation-systems-and-engineering-excellence/)

See also: [Anthropic Interview Guide 2026: Process, Questions, and AI Safety](https://www.techinterview.org/?p=3233460282)
