On this page
Step 1: Understand the Requirements First
Functional Requirements
Non-Functional Requirements
Scale Estimates
Step 2: Design the High-Level Architecture
The Core Components
Step 3: Design the Database Schema
Users Table
Photos Table
Followers Table
Which Database to Use?
Step 4: Handle Photo Upload and Storage
The Upload Flow
Why Separate the Upload Service?
Step 5: Build the News Feed
Two Approaches to Feed Generation
The Hybrid Approach (What Instagram Actually Does)
Feed Ranking
Step 6: Make It Fast with Caching
What to Cache
Cache Eviction
Step 7: Scale Globally with CDNs and Replication
Step 8: Handle Failures Gracefully
Conclusion: Key Takeaways
How to Design Instagram: A System Design Interview Walkthrough


On This Page
Step 1: Understand the Requirements First
Functional Requirements
Non-Functional Requirements
Scale Estimates
Step 2: Design the High-Level Architecture
The Core Components
Step 3: Design the Database Schema
Users Table
Photos Table
Followers Table
Which Database to Use?
Step 4: Handle Photo Upload and Storage
The Upload Flow
Why Separate the Upload Service?
Step 5: Build the News Feed
Two Approaches to Feed Generation
The Hybrid Approach (What Instagram Actually Does)
Feed Ranking
Step 6: Make It Fast with Caching
What to Cache
Cache Eviction
Step 7: Scale Globally with CDNs and Replication
Step 8: Handle Failures Gracefully
Conclusion: Key Takeaways
Every single day, hundreds of millions of photos get uploaded to Instagram.
That is an insane amount of data flowing through servers, getting stored, getting processed, and then getting delivered to screens all over the world. And somehow, it all happens in milliseconds.
Here is what makes this interesting.
Behind that simple "post a photo" button is one of the most complex distributed systems ever built. There are databases deciding where your photo lives. There are servers compressing your image into five different sizes. There are caching layers making sure your friend in Tokyo sees your post just as fast as your friend sitting next to you.
System design interviews love asking candidates to design Instagram because it touches so many fundamental concepts. You have to think about storage, databases, caching, content delivery, feed generation, and scaling.
If you can design Instagram well, you basically prove that you understand how large-scale systems work.
This walkthrough will take it step by step. No assumptions about what you already know. Every technical term gets explained the moment it shows up.
By the end, you will have a solid mental model for designing a photo-sharing platform from scratch.
Step 1: Understand the Requirements First
Before writing a single line on the whiteboard, you need to know what you are building. This is the first thing interviewers want to see. Can you ask the right questions?
Functional Requirements
These are the things the system must do:
- Upload photos with captions
- View a news feed showing posts from people you follow
- Follow and unfollow other users
- Search for users
Keep it focused.
Interviewers do not expect you to design every Instagram feature. Stories, Reels, Direct Messages, and ads are all out of scope unless they specifically ask for them.
Non-Functional Requirements
These describe how well the system should perform:
-
High availability means the system should almost never go down. If Instagram is down for even five minutes, millions of users are affected.
-
Low latency means things should feel instant. When someone scrolls their feed, photos should load in under 200 milliseconds.
-
Eventual consistency is acceptable here. This means if you post a photo, it is okay if your followers see it after a tiny delay (a few seconds) rather than instantly. The system does not need to guarantee real-time delivery to every single follower the exact same millisecond.
Scale Estimates
Interviewers love when you do quick math to understand the scale. Here is a rough estimate:
- 500 million daily active users
- 100 million new photos uploaded per day
- Average photo size: 2 MB
- That means roughly 200 TB of new storage per day just for photos
- Read-heavy system: people browse way more than they post. Assume a 100:1 read-to-write ratio
These numbers tell you something critical. This system needs to be optimized for reads, and you need a serious storage strategy.
Step 2: Design the High-Level Architecture
Now you sketch the big picture. Think of this as the blueprint before building a house. You need to know where the major pieces go before worrying about the details.
The Core Components
At the highest level, Instagram needs these pieces:
Clients are the mobile apps and web browsers that users interact with. They send requests to your backend.
Load Balancers sit in front of your servers and distribute incoming traffic evenly. Without them, one server could get crushed with requests while another sits idle. A load balancer is basically a traffic cop for your servers.
Application Servers handle the actual business logic. When someone uploads a photo or requests their feed, these servers process that request.
Database Layer stores all the structured data: user profiles, who follows whom, photo metadata (captions, timestamps, locations).
Object Storage is where the actual photo files live. You do not store images in a database. That would be painfully slow and expensive. Instead, you use something designed specifically for storing large files. Think of object storage as a massive, highly reliable hard drive in the cloud.
CDN (Content Delivery Network) is a network of servers spread across the globe that cache copies of your photos. When someone in London views a photo uploaded by someone in New York, the CDN serves it from a server in London instead of fetching it all the way from New York. This is what makes photo loading feel instant.
Step 3: Design the Database Schema
The database schema is the blueprint for how your data is organized. Getting this right is crucial.
Users Table
This stores basic profile information:
- UserID (primary key, unique identifier)
- Username
- Bio
- ProfilePhotoURL
- CreatedAt
Photos Table
Every uploaded photo gets a record here:
- PhotoID (primary key)
- UserID (who uploaded it, this is a foreign key linking back to the Users table)
- PhotoURL (the link to where the actual image file is stored in object storage)
- Caption
- CreatedAt
- Location (optional)
Followers Table
This tracks the social graph, meaning who follows whom:
- FollowerID (the person doing the following)
- FolloweeID (the person being followed)
- CreatedAt
Which Database to Use?
For structured data with clear relationships (users, follows, photo metadata), a relational database works well. Something built on SQL where you can run queries to join tables together.
But here is the catch.
At Instagram's scale, a single database server cannot handle the load. You need to split the data across multiple servers. This is called sharding.
Sharding means breaking your database into smaller pieces (called shards) and putting each piece on a different server.
A common approach: shard by UserID.
All data for a specific user lives on the same shard. This keeps most queries fast because you rarely need to look across multiple shards for a single user's data.
Step 4: Handle Photo Upload and Storage
Uploading is where things get interesting.
A user taps "Share," and a 2 MB image file needs to travel from their phone to your servers, get processed, and get stored permanently.
The Upload Flow
Here is what happens step by step:
- The client sends the photo to an upload service through the load balancer.
- The upload service stores the original photo in object storage and gets back a URL.
- The upload service then creates multiple versions of the photo (thumbnail, medium, full-size) using an image processing worker. This is called image resizing. You generate different sizes so the app can load a tiny thumbnail for the feed and a full-size image only when someone taps on it.
- The metadata (PhotoID, UserID, URL, caption) gets written to the database.
- A notification is sent to the feed generation system saying "hey, this user just posted something."
Why Separate the Upload Service?
Photo uploads are slow and resource-heavy compared to other operations.
If your upload logic and feed-serving logic share the same servers, a spike in uploads could slow down everyone's feed. Separating them means each service can scale independently. You can add more upload servers during peak hours without touching the feed servers.
Step 5: Build the News Feed
The news feed is the heart of Instagram. It is also the hardest part to design well.
When a user opens the app, they expect to see recent posts from people they follow, ordered in a way that feels relevant.
Two Approaches to Feed Generation
Pull Model (Fan-out on Read): When a user opens their feed, the system goes and collects posts from everyone they follow at that moment. It queries the database for the latest posts from each person, merges them, sorts them, and returns the result.
The problem?
If you follow 500 people, that is 500 queries every time you refresh.
At scale, this is too slow.
Push Model (Fan-out on Write): When someone posts a photo, the system immediately pushes that post into a pre-built feed for every single one of their followers. Each user has a feed cache, which is basically a pre-assembled list of posts waiting for them. When they open the app, the feed is already there. Just read it and display it.
The problem?
If a celebrity with 50 million followers posts a photo, the system has to write that post into 50 million individual feed caches.
That is a massive burst of writes.
The Hybrid Approach (What Instagram Actually Does)
Use the push model for regular users (most people have a manageable number of followers).
Use the pull model for celebrities and high-follower accounts.
When you open your feed, the system reads your pre-built feed cache and also does a quick pull for posts from any celebrities you follow. Then it merges the two together.
This gives you the speed of pre-built feeds for 99% of cases while avoiding the explosion of writes when a celebrity posts.
Feed Ranking
A simple reverse-chronological feed (newest first) works for a basic design.
But in a real interview, mention that Instagram uses a ranking algorithm that considers factors like how often you interact with the poster, how recent the post is, and how much engagement the post is getting.
This tells the interviewer you understand that feed generation is not just a data retrieval problem but also a relevance problem.
Step 6: Make It Fast with Caching
At this scale, hitting the database for every request would be a disaster.
Caching is what makes the system feel fast.
A cache is a layer of fast, temporary storage that sits between your application servers and the database.
When a user requests data, the server checks the cache first. If the data is there (a "cache hit"), it returns it instantly without touching the database. If the data is not there (a "cache miss"), it goes to the database, gets the data, stores a copy in the cache, and then returns it.
What to Cache
- User profiles that get viewed frequently
- The news feed for each user (this is the feed cache mentioned earlier)
- Photo metadata so you do not query the database every time someone views a post
- Follower counts and other frequently accessed numbers
Cache Eviction
Caches have limited memory, so you need a strategy for removing old data. LRU (Least Recently Used) is the most common approach. When the cache is full and you need to store something new, you remove the item that has not been accessed for the longest time.
Step 7: Scale Globally with CDNs and Replication
Users are everywhere. Your servers cannot be in just one location.
CDNs solve the photo delivery problem. When a photo is uploaded, copies get distributed to CDN servers around the world.
A user in Turkey gets the photo from a nearby CDN node instead of a server in the United States. This slashes load times dramatically.
Database replication means keeping copies of your database across multiple data centers. You have a primary database that handles writes and several replicas that handle reads.
Since the system is read-heavy (100:1 ratio, remember), this setup works perfectly.
Most requests go to the replicas, keeping the primary database from getting overwhelmed.
Step 8: Handle Failures Gracefully
Things will break. Servers will crash, networks will go down, disks will fail.
A good system design accounts for this.
-
Redundancy means having backups for everything. Multiple application servers, multiple database replicas, multiple copies of every photo. If one server dies, others pick up the load.
-
Message queues help with upload processing. Instead of processing a photo synchronously (making the user wait), you drop the upload task into a queue. A worker picks it up and processes it in the background. If the worker crashes, the task stays in the queue and another worker picks it up. The user is not affected.
-
Monitoring and alerting let your team know when something is going wrong before users start complaining. Track metrics like request latency, error rates, cache hit ratios, and server health.
For system design interview preparation, check out Grokking the System Design Interview course by DesignGurus.io.
Conclusion: Key Takeaways
Here is everything distilled down to what matters most:
-
Always start with requirements. Clarify functional and non-functional requirements before designing anything. This shows the interviewer you think before you build.
-
Separate storage concerns. Use a relational database for structured data and object storage for photos. Never store large files in a database.
-
The news feed is the hardest part. A hybrid push/pull approach handles both regular users and celebrity accounts efficiently.
-
Caching is non-negotiable at scale. Cache feeds, user profiles, and photo metadata to avoid crushing your database.
-
CDNs make global delivery fast. Distribute photocopies worldwide so users get content from the nearest server.
-
Design for failure. Redundancy, message queues, and monitoring keep the system running when individual components break.
-
Sharding enables horizontal scaling. Split your database by UserID so no single server becomes a bottleneck.
-
Always estimate scale. Quick back-of-the-envelope math helps you justify your design decisions and impress your interviewer.
That is how you design Instagram in a system design interview.
Start simple, go deeper where it matters, and always explain why you are making each decision.
Interviewers care less about getting the "perfect" answer and more about watching how you think through the problem.
Check out the detailed tutorial for designing Instagram.
What our users say
Steven Zhang
Just wanted to say thanks for your Grokking the system design interview resource (https://lnkd.in/g4Wii9r7) - it helped me immensely when I was interviewing from Tableau (very little system design exp) and helped me land 18 FAANG+ jobs!
Brandon Lyons
The famous "grokking the system design interview course" on http://designgurus.io is amazing. I used this for my MSFT interviews and I was told I nailed it.
ABHISHEK GUPTA
My offer from the top tech company would not have been possible without this course. Many thanks!!
Designgurus on Substack
Deep dives, systems design teardowns, and interview tactics delivered daily.
Access to 50+ courses
New content added monthly
Certificate of completion
$29.08
/month
Billed Annually
Recommended Course

Grokking the Advanced System Design Interview
38,626+ students
4.1
Grokking the System Design Interview. This course covers the most important system design questions for building distributed and scalable systems.
View CourseRead More
7 Must-Read System Design Papers to Ace Your Interview (2024 Edition)
Arslan Ahmad
Amazon System Design Mock Interview Preparation Guide
Arslan Ahmad
System Design Interview Guide 2025 – Ace FAANG & Top Tech Interviews
Arslan Ahmad
Mastering the API Interview: Common Questions and Expert Answers
Arslan Ahmad