Designing Instagram in a mobile interview is different from designing it as a backend system. The interviewer wants to see if you understand the client realities: cellular bandwidth costs money, scrolling has to feel instant, photos uploaded over flaky LTE need to survive app suspension, and the feed has to keep working when the user is on the subway.
Functional requirements
- Browse a personalized feed of photos and videos. Interviewers want to hear about pagination, prefetch, and picking image resolution per device — the ranking model itself lives on the server and is not what a mobile round is testing.
- Watch Stories (24-hour ephemeral content). Design for auto-advance, tap-to-skip, and aggressive prefetch so the next item is decoded before the user taps. The 24-hour TTL means the client works off a manifest with expiry timestamps rather than caching content forever.
- Upload photos with filters and edits. The interesting part is the edit-then-upload flow surviving app suspension. Show that filters run on the GPU and the final file is handed to a background uploader, not a foreground network call the OS can suspend.
- Like, comment, and DM. Likes and comments are optimistic writes — update the UI immediately and reconcile with the server afterward. DM pushes you toward a real-time messaging layer with delivery receipts and offline queueing.
- Search by hashtag, user, location. Scope it: typeahead for users and hashtags needs low-latency prefix queries, while location search relies on a geo index. Say plainly that search is server-driven and note what the client caches (recent queries, thumbnails).
Non-functional
- Feed first paint under 500ms; image load under 1s on 4G. First paint means showing cell structure and text before images arrive, so render placeholders immediately and stream images in. Interviewers probe how you measure this — cold start versus warm, and what actually counts as “painted.”
- Smooth 60fps scroll. Every frame has a ~16ms budget, so image decode and layout must happen off the main thread. Dropped frames almost always trace back to synchronous decode or auto-layout on variable-height cells.
- Upload survives app backgrounding and network drops. This is the requirement that separates a mobile answer from a backend one. Point to OS background-transfer APIs and resumable, chunked uploads so a killed app resumes where it left off.
- Reasonable cellular data usage. Pick resolutions by network type, respect data-saver settings, and skip background prefetch on cellular. Name the tradeoff out loud: prefetching helps scroll feel instant but spends the user’s data plan.
Feed pipeline
Server returns a paginated feed with ~10 items per page. Each item has a CDN URL for the photo at multiple resolutions (e.g., 320, 640, 1080 wide).
Client uses a feed adapter: as the user scrolls, prefetch the next page when they reach the 60% mark. Image loading is deferred until cells are ~2 screens away, at which point we fetch the appropriate resolution for the device.
Photo upload pipeline
The hardest path. The user picks a photo, applies filters, taps post, then immediately scrolls away or backgrounds the app. We need to:
- Apply filters in a GPU-accelerated pipeline (Metal on iOS, OpenGL ES on Android)
- Re-encode at upload resolution (1080 wide, JPEG q85)
- Hand the file to a background uploader (URLSession background config on iOS, WorkManager on Android)
- The uploader resumes if the app is killed; reports progress when foreground
- Server returns post ID; client updates feed with optimistic insert
Stories
Stories are videos and photos with auto-advance. Prefetch the next 2 stories aggressively. When the user taps right, the next is already decoded and ready. Stories are paged from a per-user manifest that lists all available stories with TTLs.
Caching
Three-tier cache: in-memory NSCache/Glide-style memory cache (~50MB), on-disk LRU (~500MB), and the network. Eviction is size-based, not just LRU — we keep small thumbnails longer.
Battery and data
- Pause auto-play of videos in feed when on cellular if user has data-saver enabled. Auto-play is the biggest silent data drain, so gate it on both connection type and the user’s explicit setting rather than one alone.
- Don’t prefetch in background. Background prefetch burns battery and data for content the user may never see; wake only for critical work like finishing an in-flight upload.
- Compress images on upload using HEIF when both server and device support it. HEIF roughly halves JPEG size at the same quality, but negotiate support first and keep a JPEG fallback so older servers and devices still work.
Frequently Asked Questions
How do you make scroll feel instant?
Recycle cells aggressively, decode images off the main thread, hold a small placeholder in memory, and never block UI on network IO. Pre-rendered cell heights (no auto-layout for the photo aspect) help too.
What if the user uploads a 50MB photo on bad network?
Resumable upload with chunks (e.g., 1MB chunks via tus protocol or signed multipart S3). Background URLSession can resume across app launches.
How do you rank the feed?
Server-side ranking model considers recency, relationship strength, engagement signals, and content type. Client receives a pre-ranked list; in some implementations the client reorders the top-K based on local signals (e.g., last viewed item).
Keep sharpening your system design:
