Skip to content
Devgo

Instagram

Photo sharing with a feed and sharding by user

Instagram stores photos in and metadata in a sharded setup, originally sharding by user id across many instances. The feed is a reverse-chronological/precomputed timeline. Media is served via ; 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 .

High-level diagram

Instagram architectureA block diagram of the Instagram system's main components and request flow.ClientUploadObject storageSharded PGby user idMemcachedCDN
Illustrative block diagram of Instagram. Not to scale; see the request path below for flow.

Request path

  1. Upload. Client uploads the photo; stored in ; a metadata row (id, owner, time, caption) is written to the user's shard.
  2. Feed fan-out. New post fanned out to followers' feeds (precomputed or built on read depending on scale).
  3. View feed. Feed service returns post ids; metadata fetched from the right shard; media URLs point to .
  4. Render. Client loads media from ; 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 , served via . Counts denormalized/cached.

Storage / cache / queue choices

Storage

Sharded by user id (historically many instances); for media.

Cache

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 ; 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).

, , , ,

Sources