Photo sharing with a feed and sharding by user
Instagram stores photos in object storage and metadata in a sharded PostgreSQL setup, originally sharding by user id across many instances. The feed is a reverse-chronological/precomputed timeline. Media is served via CDN; metadata via sharded DBs with caching.
Product constraints
- Read-heavy: feed and profile views dominate.
- Photos are large blobs; metadata is small and relational.
- Per-user data must be co-located for fast profile/feed queries.
- Global audience; media via CDN.
High-level diagram
Request path
- Upload. Client uploads the photo; stored in object storage; a metadata row (id, owner, time, caption) is written to the user's shard.
- Feed fan-out. New post fanned out to followers' feeds (precomputed or built on read depending on scale).
- View feed. Feed service returns post ids; metadata fetched from the right shard; media URLs point to CDN.
- Render. Client loads media from CDN; counts and captions from metadata.
Data model
Posts: (id, owner_id, created_at, media_url, caption) sharded by owner_id. Users and follows in a graph/sharded store. Media in object storage, served via CDN. Counts denormalized/cached.
Storage / cache / queue choices
Storage
Sharded PostgreSQL by user id (historically many instances); object storage for media.
Cache
Memcached for hot metadata, feeds, and counts.
Queue
Async workers for feed fan-out and notifications.
Scaling levers
- Shard metadata by user id so a user's posts are on one shard.
- Serve media from CDN; only metadata hits the DB.
- Cache feeds and counts; denormalize to avoid aggregations.
- Async fan-out for feed distribution.
Copy vs skip (for a smaller team)
Copy
- Store media in object storage + CDN, not the DB.
- Shard metadata by user id.
- Cache feeds and counts aggressively.
- Denormalize counts to avoid COUNT queries.
Skip
- Storing images in the DB (never).
- Cross-shard joins for a feed (shard by user).
- Building feeds on every read at scale (precompute or cache).
Related terms
Object storage, CDN, Sharding key, PostgreSQL, Memcached