News Feed System Design Template (Reference Design)
Social feed: hybrid fan-out on write and read, celebrity threshold, ranking pipeline, feed cache, snapshot pagination, media
Як використовувати: Use when building a follow-based feed. Fill the follower distribution (not just averages) before choosing the push/pull threshold. The main pitfall is pure fan-out on write, which breaks for accounts with huge followings.
Перегляд
System Design: [News feed name]
Reference design for a social news feed: users follow other accounts and see a ranked, paginated feed of their posts. It covers hybrid fan-out (push for most authors, pull for accounts with very large followings), a ranking pipeline, feed caching, cursor pagination, media delivery and the consistency the product can tolerate. It follows the structure of the System Design Document template and is pre-filled with a worked design to adapt. Every value marked Example is an assumption: replace it and recompute.
Document control
| Field | Value |
|---|---|
| Document ID | [SDD-FEED-001] |
| System / feature | [Home feed] |
| Version | [0.1] |
| Status | [Draft / In review / Approved / Implemented / Superseded] |
| Author(s) | [@author] |
| Reviewers | [@reviewer-1], [@reviewer-2] |
| Last updated | YYYY-MM-DD |
| Related | [PRD], [Ranking model card], [ADR: fan-out strategy] |
Approvals
| Role | Name | Decision | Date |
|---|---|---|---|
| Tech lead | [@name] | [Approved / Changes requested] | YYYY-MM-DD |
| Staff / principal engineer | [@name] | [Decision] | YYYY-MM-DD |
| SRE / operations | [@name] | [Decision] | YYYY-MM-DD |
| Ranking / ML lead | [@name] | [Decision] | YYYY-MM-DD |
| Trust and safety | [@name] | [Decision] | YYYY-MM-DD |
Revision history
| Version | Date | Author | Change summary |
|---|---|---|---|
| 0.1 | YYYY-MM-DD | [@name] | First draft for design review |
| 0.2 | YYYY-MM-DD | [@name] | Example: Hybrid fan-out with threshold at 10 000 followers |
| 0.3 | YYYY-MM-DD | [@name] | Example: Two-stage ranking (candidate retrieval, then scoring) |
| 1.0 | YYYY-MM-DD | [@name] | Example: Approved |
Contents
1. Overview
1.1 Problem statement
[Example: The current feed is computed on every request by querying posts from all followed accounts. p99 latency is 2.4 s for users following more than 1 000 accounts, the database is at 80% CPU at peak, and the order is purely chronological, so engagement drops when users follow active accounts.]
1.2 Proposed solution
[Example: When an author with fewer than 10 000 followers posts, a fan-out service writes the post ID into each follower's precomputed feed in an in-memory store (push). Posts from accounts above the threshold are fetched at read time and merged (pull). A feed service combines both candidate sets, filters blocked and deleted content, ranks with a lightweight model and returns a page with an opaque cursor. Post bodies and media are hydrated from caches and a CDN.]
1.3 Decisions requested from reviewers
| ID | Question | Recommended option | Section |
|---|---|---|---|
| Q-01 | Example: Fan-out on write, on read, or hybrid? | Hybrid, threshold 10 000 followers | 7.2, 10 |
| Q-02 | Example: How long is the precomputed feed? | 800 entries per active user | 3.4, 7.3 |
| Q-03 | Example: Do we fan out to inactive users? | No; rebuild on return | 7.3 |
| Q-04 | Example: Is pagination stable while new posts arrive? | Yes, cursor holds a ranked snapshot ID | 7.5 |
| [Q-nn] | [Question] | [Option] | [Section] |
2. Requirements
2.1 Functional requirements
| ID | Requirement | Priority |
|---|---|---|
| FR-01 | Example: Create a post with text and up to 4 images or one video | Must |
| FR-02 | Example: Follow and unfollow accounts | Must |
| FR-03 | Example: Show a ranked home feed of followed accounts' posts | Must |
| FR-04 | Example: Paginate with infinite scroll; no duplicates or skips within a session | Must |
| FR-05 | Example: Show a "new posts" pill when fresh content is available | Should |
| FR-06 | Example: Remove deleted, blocked or muted content from feeds within 1 min | Must |
| FR-07 | Example: Offer a chronological view as a user option | Should |
| [FR-nn] | [Requirement] | [Must / Should / Could] |
2.2 Non-functional requirements
| ID | Quality | Target | Measured as |
|---|---|---|---|
| NFR-01 | Latency | Example: Feed page p99 at or below 250 ms server time | Service metrics |
| NFR-02 | Availability | Example: 99.95% monthly for feed reads | Synthetic checks |
| NFR-03 | Freshness | Example: A new post appears in followers' feeds within 10 s at p95 | Canary account probe |
| NFR-04 | Durability | Example: No acknowledged post is lost | RF=3, backups |
| NFR-05 | Correctness | Example: Deleted posts never shown after 60 s | Deletion probe |
| [NFR-nn] | [Quality] | [Target] | [Measurement] |
2.3 Out of scope
- [Example: recommendations from accounts the user does not follow]
- [Example: ads insertion (separate design; reserved slots only)]
- [Example: comments and reactions storage]
- [Item deferred, with the release that will take it]
3. Capacity estimation
3.1 Assumptions
| Input | Symbol | Value | Source |
|---|---|---|---|
| Daily active users | Example: 300 million | Growth plan | |
| Feed page requests per user per day | Example: 10 | Product analytics | |
| Posts per user per day | Example: 0.2 | Product analytics | |
| Average followers per author (below threshold) | Example: 200 | Follow graph | |
| Stored post record (text + metadata) | Example: 1 KB | Schema in 5.2 | |
| Feed entry (post ID + author ID + score) | Example: 20 bytes | 7.3 | |
| Feed length kept per user | Example: 800 entries | Decision Q-02 | |
| Peak to average factor | Example: 3 | Traffic history |
3.2 Throughput
Feed reads:
Posts:
Fan-out writes (feed inserts):
3.3 Why the celebrity case breaks push
One post from an account with followers would require inserts. At 420 000 inserts/s of spare capacity that single post would take about 2 minutes to fan out and would delay every other post behind it. This is why accounts above the threshold are pulled at read time.
3.4 Storage and memory
Posts per year:
Precomputed feeds in memory (all daily active users):
With one replica that is 9.6 TB of memory, for example about 150 nodes with 64 GB usable each. Reducing to 400 halves it; measure how deep users actually scroll before deciding.
Media (separate object store):
assuming 20% of posts carry media averaging 500 KB after compression.
3.5 Summary
| Quantity | Estimate | Design consequence |
|---|---|---|
| Feed reads | ~35 000/s average, ~104 000/s peak | Serve from precomputed in-memory feeds |
| Fan-out inserts | ~140 000/s average, ~420 000/s peak | Asynchronous workers; skip inactive users |
| Feed memory | ~4.8 TB, ~9.6 TB with replica | Sharded in-memory store; length cap |
| Post storage | ~22 TB/year logical | Partitioned post store; body cache |
| Media | ~6 TB/day | Object storage plus CDN, never through feed service |
4. API design
4.1 Endpoints
| Method | Path | Purpose | Auth | Idempotent |
|---|---|---|---|---|
| POST | /v1/posts | Create a post | User token | With Idempotency-Key |
| DELETE | /v1/posts/{id} | Delete own post | User token | Yes |
| GET | /v1/feed?cursor=&limit=20 | Home feed page | User token | Yes |
| GET | /v1/feed/new-count?since= | Count of newer items for the "new posts" pill | User token | Yes |
| PUT / DELETE | /v1/follows/{accountId} | Follow or unfollow | User token | Yes |
4.2 Request and response examples
A feed page returns hydrated items plus an opaque cursor for the next page:
GET /v1/feed?limit=20 HTTP/1.1
Authorization: Bearer [token]
{
"items": [
{"postId": "p_7a91", "author": {"id": "a_12", "name": "City Library"}, "text": "Late opening hours start Monday.", "media": [{"type": "image", "url": "https://media.example/p_7a91/0.webp"}], "createdAt": "2026-03-14T08:01:00Z", "reason": "followed"}
],
"nextCursor": "eyJzbmFwIjoiczg4MiIsIm9mZiI6MjB9"
}
4.3 Errors, limits and versioning
| Status | Problem type | When |
|---|---|---|
| 400 | invalid-cursor | Cursor malformed or expired (older than 30 min); client restarts from top |
| 413 | media-too-large | Upload exceeds limit |
| 429 | rate-limited | Post or follow rate exceeded; Retry-After set |
- Rate limits: [Example: 50 posts per hour, 400 follows per day per user].
- Versioning:
/v1path prefix; feed item schema is additive only.
5. Data model
5.1 Entities
Posts, the follow graph and the per-user precomputed feed are the three core data sets; engagement events feed ranking.
5.2 Storage choices
| Data | Store | Partition key | Main queries | Why |
|---|---|---|---|---|
| Posts | Example: Wide-column or sharded relational store | post_id (with author index) | Get by IDs (batch); recent by author | Batch point reads for hydration |
| Follow graph | Example: Sharded store with both directions materialised | follower_id and followee_id | Followers of X (fan-out); followees of Y (pull) | Both directions are hot |
| Precomputed feeds | Example: In-memory sorted sets | user_id | Top N by score; trim to | Sub-millisecond reads |
| Author recent posts | In-memory list per pull author | author_id | Latest 200 posts | Cheap merge for celebrities |
| Engagement events | Event log, then feature store | user_id | Ranking features | Streaming aggregation |
| Media | Object storage + CDN | Content hash | Get by URL | Large objects off the hot path |
6. High-level design
The write path (post, fan-out) and the read path (feed, rank, hydrate) share only the stores.
| Component | Responsibility | Scales by |
|---|---|---|
| Post service | Validate, store posts, emit events, handle deletes | Stateless replicas |
| Fan-out workers | Read follower lists in pages, insert into active followers' feeds | Consumer partitions |
| Feed service | Merge pushed and pulled candidates, filter, call ranking, paginate | Stateless replicas |
| Ranking service | Score candidates with features | Model replicas, GPU or CPU |
| Hydration | Batch fetch post bodies, author profiles, counters | Cache cluster size |
| [Component] | [Responsibility] | [Scaling unit] |
7. Detailed design
7.1 Feed read (critical path)
The feed service reads the pushed feed and pulled candidates in parallel, then ranks and hydrates only the page it returns.
If ranking times out (budget 60 ms), the service falls back to base_score
order (recency with author affinity) so the user always gets a page.
7.2 Hybrid fan-out
- An account becomes a pull author when
follower_countexceeds Example: 10 000, with hysteresis (back to push below 8 000) to avoid flapping. - Push: on a post event, workers page through the author's followers
(1 000 per batch) and insert
(post_id, author_id, base_score)into each active follower's sorted set, trimming to entries. - Pull: on read, the feed service fetches the latest posts of each pull author the user follows. Most users follow few such accounts; cap at Example: 200 pull authors per user, chosen by affinity.
- Inactive users (no session for 14 days) are skipped during fan-out. When they return, the feed is rebuilt from followees' recent posts in the background, and the first page is served by a pull-only path meanwhile.
7.3 Feed cache layout
Each user's feed is a sorted set keyed by feed:{user_id}, scored by a
time-decayed base score so trimming keeps the most relevant recent items.
Entries hold IDs only; bodies live in the post cache so edits and deletes take
effect without rewriting feeds. A deletion event adds the post to a
short-lived tombstone set consulted by the filter step, and a background job
removes the entries.
7.4 Ranking pipeline
| Stage | Input | Output | Budget |
|---|---|---|---|
| Candidate generation | Pushed feed + pulled authors | Up to 500 candidates | 20 ms |
| Filtering | Blocks, mutes, deleted, already seen in last 24 h | Valid candidates | 5 ms |
| Scoring | Features: author affinity, post age, engagement velocity, media type | Predicted engagement score | 60 ms |
| Re-ranking | Diversity rules (max 2 consecutive posts per author), freshness boost | Final order | 5 ms |
A typical score combines predicted actions with weights and an age decay:
where is the half-life, for example 6 hours. Weights are set by product goals and reviewed for integrity effects (for example down-weighting predicted outrage).
7.5 Pagination and consistency model
- The first page call stores the ranked list of up to 500 IDs as a snapshot
for 30 minutes; the cursor encodes
snapshot_idand offset. Later pages read the snapshot, so new posts never shift items and cause duplicates or skips. - New content is surfaced through
new-count, and pulling to refresh creates a new snapshot. - Consistency: feeds are eventually consistent. A post appears in pushed feeds within seconds; follows take effect on the next snapshot; unfollows and blocks are enforced by the filter step at read time, so they apply immediately even before fan-out entries are cleaned up.
- Read-your-writes: the author's own new posts are injected into their first page from the post service, independent of fan-out lag.
7.6 Media
Clients upload media directly to object storage with pre-signed URLs; a processing job produces resized WebP/AVIF variants and video renditions, and the post becomes visible only when its media are ready. Feed items reference CDN URLs with content-hash names so they can be cached for a year.
8. Scalability and performance
| Concern | Approach | Limit before redesign |
|---|---|---|
| Fan-out volume | Skip inactive users; pull authors above threshold | Example: ~1 million inserts/s with 512 worker partitions |
| Feed cache memory | Length cap, IDs only, active users only | Memory per node; reshard by user_id hash |
| Hot posts | Post body cache with request coalescing | One viral post at ~500 000 reads/s via local caches |
| Ranking cost | Score at most 500 candidates; cache scores per snapshot | Model latency budget 60 ms |
| Follow graph reads | Followers paged; pull-author list cached per user | [Limit] |
Latency budget for a first feed page (target p99 250 ms):
| Step | Budget |
|---|---|
| Gateway and auth | 15 ms |
| Candidate fetch (parallel) | 30 ms |
| Merge and filter | 10 ms |
| Ranking | 60 ms |
| Hydration | 40 ms |
| Serialisation | 10 ms |
| Headroom | 85 ms |
9. Reliability, security and operations
9.1 Failure modes
| Failure | Impact | Detection | Mitigation |
|---|---|---|---|
| Feed cache node lost | Affected users get empty pushed feeds | Cache error rate | Pull-only fallback for those users; rebuild from followees in background |
| Fan-out backlog | New posts appear late | Consumer lag | Autoscale workers; prioritise recent posts; NFR-03 alert |
| Ranking service down | Lower quality order | Error and timeout rate | Fallback to base_score order |
| Post store partition unavailable | Some posts cannot hydrate | Hydration miss rate | Drop unhydratable items from the page rather than fail it |
| Deletion event lost | Deleted post still shown | Deletion probe | Filter checks post state during hydration as a second guard |
| [Failure] | [Impact] | [Signal] | [Mitigation] |
9.2 Security and abuse
| Threat | Control |
|---|---|
| Private posts leaking to non-followers | Visibility checked at hydration against current follow and audience settings |
| Spam accounts mass-following to harvest content | Follow rate limits, new-account restrictions |
| Coordinated inauthentic engagement gaming ranking | Engagement features weighted by account trust; anomaly detection |
| Harmful content amplification | Integrity classifiers feed a demotion signal; removal events honoured within 60 s |
| [Threat] | [Control] |
9.3 Observability
| Signal | Metric or log | Alert threshold |
|---|---|---|
| Feed latency | p50, p99 | p99 above 250 ms for 10 min |
| Freshness | Canary post visible in canary follower feed | Above 30 s |
| Fallback rate | Pages served without ranking | Above 2% for 10 min |
| Empty feeds | Pages with zero items for users with followees | Above 0.1% |
| Fan-out lag | Consumer lag | Above 60 s |
9.4 Cost estimate
| Item | Unit cost | Quantity | Monthly cost |
|---|---|---|---|
| Feed cache memory | [$/GB-month] | Example: 9.6 TB | [$] |
| Fan-out and feed services | [$/node-month] | [n] | [$] |
| Ranking inference | [$/million scores] | Example: ~500 candidates x first pages | [$] |
| Post store | [$/TB-month] | Example: 66 TB per year of growth | [$] |
| Media storage and CDN egress | [$/TB] | Example: 180 TB/month new media | [$] |
| Total | [$] |
10. Trade-offs and alternatives
| Decision | Options | Chosen | Why | What we give up |
|---|---|---|---|---|
| Fan-out | Pure push; pure pull; hybrid | Hybrid | Fast reads for most users, bounded write cost for celebrities | Two candidate paths, threshold tuning |
| Feed contents | Full post copies; IDs only | IDs only | Small memory, edits and deletes apply instantly | Hydration step on every read |
| Inactive users | Fan out to all; skip inactive | Skip | Large saving in writes and memory | Slower first load after a long absence |
| Pagination | Offset; time cursor; snapshot cursor | Snapshot cursor | No duplicates or skips while ranking changes | Snapshot storage, 30 min expiry |
| Ranking | Chronological; single heavy model; two-stage | Two-stage, light scorer | Fits latency budget, easy fallback | Less accuracy than a heavy model on all candidates |
| [Decision] | [Options] | [Chosen] | [Why] | [Cost] |
11. Delivery plan and risks
11.1 Milestones
| Milestone | Scope | Exit criterion | Target date |
|---|---|---|---|
| M1 | Push fan-out, chronological feed, cursor pagination | p99 under 250 ms in shadow traffic | YYYY-MM-DD |
| M2 | Pull authors and hybrid merge | Celebrity post visible to all followers in under 10 s | YYYY-MM-DD |
| M3 | Ranking v1 behind experiment | Positive or neutral on guardrail metrics in A/B test | YYYY-MM-DD |
| M4 | Inactive-user skip and rebuild | Memory down 30% with no freshness regression | YYYY-MM-DD |
11.2 Rollout and rollback
[Example: Dual-write feeds for two weeks while the old query path serves traffic; compare outputs on 1% of requests. Switch reads per percentage of users; rollback switches reads back while dual writes continue.]
11.3 Risks
| ID | Risk | Likelihood | Impact | Mitigation | Owner |
|---|---|---|---|---|---|
| R-01 | Example: Threshold flapping causes duplicate or missing posts | Medium | Medium | Hysteresis; dedupe by post_id at merge | [@name] |
| R-02 | Example: Ranking change harms wellbeing metrics | Medium | High | Guardrail metrics in every experiment; integrity review | [@name] |
| R-03 | Example: Memory cost exceeds budget | Medium | Medium | Reduce ; compress entries | [@name] |
| [R-nn] | [Risk] | [L / M / H] | [L / M / H] | [Mitigation] | [@name] |
12. Appendices
12.1 Open questions
| ID | Question | Owner | Due |
|---|---|---|---|
| OQ-01 | Example: Should muted keywords be filtered server side? | [@name] | YYYY-MM-DD |
| OQ-02 | Example: What half-life works per content type? | [@name] | YYYY-MM-DD |
| [OQ-nn] | [Question] | [@name] | YYYY-MM-DD |
12.2 Glossary
| Term | Meaning |
|---|---|
| Fan-out on write (push) | Copy a post reference into followers' feeds when it is created |
| Fan-out on read (pull) | Fetch followees' posts when the feed is requested |
| Pull author | Account whose posts are fetched at read time because of follower count |
| Hydration | Replacing IDs with full post and author data |
| Snapshot cursor | Cursor pointing at a stored ranked list for stable pagination |
| [Term] | [Meaning] |
12.3 References
| Reference | Use |
|---|---|
| RFC 9110 HTTP Semantics | API methods and caching |
| RFC 9457 Problem Details for HTTP APIs | Error format in 4.3 |
| [Internal ranking model card] | Features and evaluation for 7.4 |
Standard and licence note
Based on common industry practice for social feed system design. This is a reference design to adapt: the numbers are illustrative assumptions, not measurements. Original text written for this collection. Template licence: MIT.
Схожі шаблони
Database Design Document Template (ERD and Physical Model)
Database design: DBMS choice, conceptual, logical and physical models, indexes, partitioning, integrity, security, backup, capacity
Архітектура та системний дизайнChat System Design Template (Reference Design)
Real-time 1:1 and group chat: WebSocket gateways, per-conversation ordering, fan-out, receipts, offline sync, push, E2EE
Архітектура та системний дизайнCollaborative Editing System Design Template (Reference Design)
Real-time co-editing: OT vs CRDT, sequence CRDT, state-vector sync, presence, offline merge, snapshots and compaction, access