Top System Design Interview-Design a Social Media Feed System (2025 Edition)

Top System Design Interview-Design a Social Media Feed System (2025 Edition)

Overview

A social media feed displays posts from users you follow, ordered by relevance or time.

Requirements

Functional:

  • Users can follow/unfollow others.
  • Users post messages.
  • Users see a feed of posts from people they follow.
  • Feed sorted by timestamp (latest first).

Non-functional:

  • Scalable to millions of users and posts.
  • Low latency feed retrieval.
59ab53d4 df8e 43a7 868c 3385dce4406b Simply Creative Minds

Core Concepts

  • Data Model:
EntityFields
Useruser_id, name, …
Postpost_id, user_id, content, timestamp
Followfollower_id, followee_id
  • Feed Generation:

Two approaches:

  • Fan-out on write: When a user posts, push the post to followers’ feeds. Good for small follower counts.
  • Fan-out on read: On feed request, fetch latest posts from all followed users and merge. Good for large follower counts.

Simplified Python Example using fan-out-on-read (in-memory)

Step 1: Setup

JavaScript
from flask import Flask, request, jsonify
from collections import defaultdict
import time

app = Flask(__name__)

# In-memory data stores
users = set()
posts = defaultdict(list)  # user_id -> list of (timestamp, post)
follows = defaultdict(set)  # follower_id -> set of followee_ids

Step 2: Create user & follow/unfollow

JavaScript
@app.route('/user', methods=['POST'])
def create_user():
    user_id = request.json.get('user_id')
    if not user_id or user_id in users:
        return jsonify({'error': 'Invalid or existing user_id'}), 400
    users.add(user_id)
    return jsonify({'message': f'User {user_id} created'}), 201

@app.route('/follow', methods=['POST'])
def follow_user():
    follower = request.json.get('follower')
    followee = request.json.get('followee')
    if follower not in users or followee not in users:
        return jsonify({'error': 'Invalid users'}), 400
    follows[follower].add(followee)
    return jsonify({'message': f'{follower} followed {followee}'}), 200

@app.route('/unfollow', methods=['POST'])
def unfollow_user():
    follower = request.json.get('follower')
    followee = request.json.get('followee')
    if follower not in users or followee not in users:
        return jsonify({'error': 'Invalid users'}), 400
    follows[follower].discard(followee)
    return jsonify({'message': f'{follower} unfollowed {followee}'}), 200

Step 3: Post creation

JavaScript
@app.route('/post', methods=['POST'])
def create_post():
    user_id = request.json.get('user_id')
    content = request.json.get('content')
    if user_id not in users or not content:
        return jsonify({'error': 'Invalid user or content'}), 400

    timestamp = time.time()
    posts[user_id].append((timestamp, content))
    return jsonify({'message': 'Post created'}), 201

Step 4: Fetch feed (fan-out-on-read)

JavaScript
@app.route('/feed/<user_id>', methods=['GET'])
def get_feed(user_id):
    if user_id not in users:
        return jsonify({'error': 'User not found'}), 404

    followees = follows[user_id]
    feed_items = []

    # Fetch last 10 posts from each followee
    for f_id in followees:
        user_posts = posts[f_id][-10:]  # last 10 posts
        feed_items.extend([(f_id, ts, content) for ts, content in user_posts])

    # Sort all posts by timestamp descending
    feed_items.sort(key=lambda x: x[1], reverse=True)

    # Limit feed size
    feed_items = feed_items[:20]

    # Format feed
    feed = [{'user_id': u, 'timestamp': ts, 'content': c} for u, ts, c in feed_items]

    return jsonify({'feed': feed}), 200

Step 5: Run the app

JavaScript
if __name__ == '__main__':
    app.run(debug=True)

Usage Example

  • Create users Alice and Bob.
  • Alice follows Bob.
  • Bob posts a message.
  • Alice fetches her feed and sees Bob’s post.

Limitations & Improvements

  • In-memory data won’t scale for real systems; use DB like Cassandra or DynamoDB.
  • Fan-out-on-read can be slow if user follows many accounts; fan-out-on-write or hybrid approaches help.
  • Add pagination for feed.
  • Add caching (Redis) for faster feed retrieval.
  • Use background workers for fan-out-on-write feeds.
  • Add ranking and filtering (e.g., relevance, promoted posts).

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *