Instagram is a social media platform where people share photos and videos, follow others, and interact through likes, comments, messages, and stories. It focuses on visual content and includes features like short-form videos (Reels), disappearing posts (Stories), and direct messaging.
Product Requirements
Functional Requirements
- Users should be able to post contents (like photos or videos)
- Users should be able to follow/unfollow others
- Users should be able to view a chronological feed of posts from people they follow
Non-Functional Requirements
- This system should prioritize availability over consistency, eventual consistency is acceptable
- For example, it is acceptable if a user sees a friend’s post with a slight delay (e.g., a few minutes later)
- This system should show feeds in low latency (< 500ms)
- The system should support high throughput and massive scale, handling hundreds of millions of daily active users (e.g., ~500M DAU)
- The system should deliver media content efficiently with low latency, ensuring fast load times for images and videos
Product Design Setup
Data Model
- User: Stores user profile information such as username, bio, profile photo, and other account metadata.
- Post: Represents a piece of user-generated content, including caption, creator, timestamps, and a reference to the associated media. A single Post entity can support both photos and videos.
- Media: Represents the actual image or video asset. The metadata may live in the application database, while the file bytes themselves are stored in an object store such as S3.
- Follow: Represents the directed relationship between two users, where one user follows another. This entity is essential for feed generation and social graph queries.
API Design
Firstly, users should be able to create posts (photos or videos), so we define a POST endpoint for creating post metadata:
POST /posts { mediaId: "abc123", caption: "my cool photo" }
We intentionally decouple media upload from post creation by using a pre-signed URL flow. This allows clients to upload large media files directly to object storage (e.g., S3), improving scalability and reducing backend load. Here, we focus only on creating the post metadata. The service returns a postId, which can be used for downstream workflows such as feed generation or notifications.
Secondly, users should be able to follow other users, so we define a follow endpoint:
POST /follow { followeeId: "user_123" }
This endpoint creates a directed relationship in the social graph, which will later be used for feed generation and recommendation.
Finally, users need to view their timeline, so we define a feed retrieval endpoint:
GET /feeds?cursor={last_post_id}&pageSize=10 -> Post[]
We use cursor-based pagination to support efficient scrolling and avoid issues with offset-based pagination at scale. This endpoint returns a list of posts ordered by relevance or recency, enabling a smooth and low-latency user experience.