Design Instagram
Problem
Design a photo and video sharing app. Users upload photos and short videos with a caption, follow other users, and scroll a feed of posts from people they follow. They can like and comment on posts and view any user's profile grid. The app has 500 million daily active users who upload about 100 million photos and videos per day and view far more. Images must load quickly on mobile networks around the world.
- What is the maximum photo size and video length?
- Which resolutions do clients need: thumbnails for the grid, a feed size, and full screen?
- How fresh must the feed be after someone I follow posts?
- Is the feed chronological or ranked?
- Do we need Stories, Reels, or direct messages, or only the main feed?
- Are private accounts in scope, where only approved followers can see posts?
Items in bold are existing requirements. The rest are suggestions. Confirm with the interviewer whether they are relevant first.
- Upload a photo or video with a caption.
- Follow and unfollow users.
- View a feed of posts from followed users.
- Like and comment on posts.
- View a user's profile grid of posts.
- Support private accounts whose posts only approved followers can see.
Items in bold are existing requirements. The rest are suggestions. Confirm with the interviewer whether they are relevant first.
- 100 million uploads per day is about 1,200 per second average and 3,500 at peak.
- Average original upload of 2 MB (photos) with videos larger: about 300 TB per day of originals and processed renditions combined.
- Reads outnumber uploads about 100 to 1: plan for over 100,000 feed and image requests per second at the origin before CDN offload.
- Feed loads in under 300 ms; images start rendering in under 200 ms on a typical mobile connection.
- Uploads must never be lost once acknowledged; processing may take a few seconds.
- Eventual consistency for likes, comment counts, and feed propagation.
Clients upload media directly to object storage using a pre-signed URL, so large files never pass through the application servers, and then create the post with metadata. A processing pipeline generates resized and transcoded versions, and all media is served through a CDN. The feed reuses the fan-out pattern: post IDs are pushed into followers' cached feeds, with high-follower accounts merged at read time, while likes and comments are stored in separate sharded tables with asynchronously aggregated counters.
Loading diagram...
Upload media. The app asks the media service for an upload slot. The service returns a media ID and a pre-signed URL into the raw media bucket. The app uploads the file directly (resumable for videos), then the bucket notifies the processing pipeline.
Process. Processing workers strip location metadata, generate renditions (150 px thumbnail, 640 px, 1080 px) in WebP and JPEG, transcode videos into adaptive bitrate HLS segments, and write results to the processed media bucket under content-addressed paths. They mark the media ID ready.
Create the post. The app calls POST /posts with media IDs and a caption. The post service writes the post (status pending until all media is ready), then emits PostPublished. Fan-out workers insert the post ID into followers' cached feeds.
View the feed. The feed service reads the cached post IDs, merges recent posts from followed high-follower accounts, ranks them, and hydrates each post with media URLs, author, caption, and counts. The app loads images from the nearest CDN edge, requesting the rendition that fits the screen.
Like and comment. Likes and comments are written to the engagement service, which updates counts asynchronously and notifies the author.
Handles uploads and turns originals into the renditions clients need.
- S3 or GCS buckets; a queue (SQS or Kafka) of processing jobs; workers using libvips for images and FFmpeg for video.
Diagram
Loading diagram...
API
POST /mediawith{ type, sizeBytes, contentType }returns{ mediaId, uploadUrl }.GET /media/:idreturns{ status, renditions }.
Scalability
Image workers are CPU bound and video workers can use GPU instances; both autoscale on queue depth independently. Direct uploads mean the API tier handles only small JSON requests regardless of file size.
Tradeoffs
Generating renditions eagerly at upload costs storage, but every image is viewed many times on many screen sizes, so precomputing avoids repeated resizing on the read path. On-the-fly resizing at the CDN is an alternative for rarely used sizes. Originals move to an infrequent-access storage class after 30 days.
Delivers media close to users.
- A commercial CDN (CloudFront, Fastly, Akamai) in front of the processed bucket.
Scalability
Media paths are content-addressed and immutable, so they are cached with long TTLs and never need invalidation. The large majority of image bytes are served from the edge; the origin sees mostly the long tail.
Tradeoffs
Signed, expiring URLs protect private account media at the cost of lower cache reuse. Public media uses plain long-lived URLs to maximize hit rate.
Stores post metadata and serves profile grids.
- Sharded PostgreSQL or Cassandra; Snowflake-style time-ordered post IDs.
API
POST /postswith{ mediaIds, caption, location? }returns{ postId }.GET /users/:id/posts?cursor=returns the profile grid.DELETE /posts/:idremoves a post.
Data Model
posts(post_id PK, author_id, caption, media_ids, created_at, visibility, deleted)user_posts(author_id, post_id DESC)for the profile grid, partitioned byauthor_id.
Tradeoffs
Partitioning the profile index by author keeps a grid page to one partition read. Popular authors' grids are cached, since a celebrity profile can get thousands of views per second.
Builds the home feed from cached post IDs and live merges.
- Stateless service; Redis Cluster for per-user feed lists; Kafka-driven fan-out workers.
Scalability
Fan-out on write for typical accounts and fan-out on read for accounts above roughly 500,000 followers keeps both write amplification and read latency bounded. Feeds of users inactive for a month are dropped and rebuilt on demand.
Tradeoffs
Storing post IDs rather than full posts in feeds means captions, deletes, and counts are read at hydration time and never need to be propagated. Private account posts fan out only to approved followers, so the read path does not need a permission check per post.
Stores likes and comments and maintains counters.
- Cassandra for likes and comments; Redis counters flushed to the post store.
Data Model
likes(post_id, user_id, created_at)partitioned bypost_id.user_likes(user_id, post_id)to show the filled heart for the viewer.comments(post_id, comment_id, author_id, text, created_at)partitioned bypost_id, clustered bycomment_id.
Scalability
A viral post can receive tens of thousands of likes per second. Increments go to sharded in-memory counters (several sub-counters per hot post, summed on read) and are flushed periodically, which avoids a hot row.
Tradeoffs
Displayed counts can lag by a few seconds, which users do not notice. The per-user like record is written synchronously, so a user always sees their own like and cannot double-like.