Social Media Feed API

This example follows the system design process from lesson 01 to design a social media feed with REST, an API gateway, and cursor pagination.

Step 1: Requirements

Functional:

  • Users create posts
  • Users see a feed of posts from people they follow
  • Users can like and delete posts
  • Feed is paginated (infinite scroll)

Non-functional:

  • Feed loads in under 200ms
  • 1 million daily active users
  • Feed can be slightly stale (eventual consistency is fine)
  • Must handle bots scraping feeds (rate limiting)

What we're NOT building: the follow system, notifications, or search. Just the feed and posts.

Step 2: Estimation

DAU: 1 million
Feed loads per user per day: 20 (scrolling multiple times)
Total feed reads: 20M/day = ~230/sec
Peak (3x): ~700 reads/sec

New posts per day: 500,000
Posts per second: ~6/sec

Read-to-write ratio: ~40:1 (heavily read)

Storage per post: 500 bytes (text, author, timestamp, metadata)
Daily post storage: 500K × 500B = 250 MB
Yearly: ~90 GB

Read-heavy system. Caching the feed will eliminate most database load. A single database with a cache in front handles this.

Step 3: High-Level Design

     Client

   API Gateway
   (auth, rate limit)

  ┌────┴────┐
  ▼         ▼
Feed      Post
Service   Service
  │         │
  ▼         ▼
Cache    Database


Database

API Gateway handles auth (validate JWT), rate limiting (300 reads/min per user, 30 posts/min), and routing (/feed → Feed Service, /posts → Post Service).

Feed Service reads from cache first. On cache miss, queries the database for posts from followed users, caches the result.

Post Service handles creates and deletes. On new post, publishes an event to invalidate/update cached feeds of followers.

Step 4: Deep Dive

API Design (REST)

POST   /v1/posts          → Create a new post
GET    /v1/feed           → Get your feed (paginated)
GET    /v1/posts/:id      → Get a single post
DELETE /v1/posts/:id      → Delete your own post
POST   /v1/posts/:id/like → Like a post

Cursor Pagination

A feed changes constantly. New posts appear at the top. Offset pagination would break:

  • You load posts 1-10 (page 1)
  • Someone you follow posts something new
  • You request page 2 (offset 10) — everything shifted down
  • Post 10 appears again on page 2. Duplicate.

Cursor pagination fixes this:

GET /v1/feed?limit=10
→ Returns posts + cursor

GET /v1/feed?limit=10&after=eyJ0IjoiMjAyNi0wNS0xOVQwOTowMCJ9
→ Returns next 10 posts after that timestamp

The cursor encodes the last post's timestamp. The query: WHERE created_at < :cursor AND author_id IN (followed_users) ORDER BY created_at DESC LIMIT 10. New posts at the top don't shift your position.

API Gateway in Action

  1. Request arrives: GET /v1/feed
  2. Gateway validates JWT → extracts user_id: u_456
  3. Gateway checks rate limit: INCR rate:u_456:feed in Redis. Under 60/min? Continue.
  4. Gateway routes to Feed Service with user_id attached
  5. Feed Service checks cache → hit? Return immediately. Miss? Query DB, cache result, return.

Versioning

/v1/feed returns {id, text, author, timestamp}. Later, /v2/feed adds {reactions_count, is_liked}. Both run simultaneously. Old mobile app versions still use v1. The gateway routes based on the URL prefix.

Response

{
  "posts": [
    {
      "id": "p_789",
      "author": "alice",
      "text": "Just deployed to production",
      "created_at": "2026-05-19T09:00:00Z",
      "reactions_count": 12
    }
  ],
  "pagination": {
    "next_cursor": "eyJ0IjoiMjAyNi0wNS0xOVQwODo1MCJ9",
    "has_more": true
  }
}

The client doesn't decode the cursor. It just passes it back on the next request.

Concepts Used

Concept Lesson How it's used here
System design process 01 Requirements → Estimation → Design → Deep dive
Estimation 02 QPS, storage, read/write ratio
Caching 07 Feed responses cached, eliminates most DB reads
Database 09 Stores posts, follows, likes
Message queues 15 New post event invalidates follower feed caches
API gateway 17 Auth, rate limiting, routing, versioning
REST + pagination 17 Resource endpoints, cursor-based feed scrolling
Rate limiting 19 Per-user limits on reads and writes
© 2026 ByteLearn.dev. Free courses for developers. · Privacy