Media & streaming, an interactive architecture walkthrough

Photo sharing platform: how the architecture works

How a photo sharing platform takes uploads straight to object storage, resizes them in the background, and builds follower feeds from cached post ids.

This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate.

31 components, 36 connections, 13 steps. Updated 4 November 2026.

Interactive diagram

Overview

A photo sharing platform takes an upload from a phone, turns it into a set of sizes that load quickly on any screen, and shows it in followers' feeds. The upload path is built so application servers never carry image bytes: the client uploads the original directly to object storage with a signed URL, and background workers do the resizing and moderation checks.

Post metadata, the follow graph, likes and comments are stored separately because they have different access patterns. The feed reuses the fan-out-on-write approach of a timeline system: each new post id is pushed into a cached list for every follower, and the feed service hydrates those ids when the app opens. This is a simplified learning design, not any company's production system.

Trade-offs and what changes at scale

Pre-generating a fixed set of sizes costs storage but keeps view latency low; resizing on demand at the CDN saves storage but adds work on cache misses. Fan-out on write makes feed reads cheap but is skipped for very large accounts, whose posts are merged in at read time. Like counts in a cache are approximate for a moment and are reconciled from the engagement store. At larger scale images dominate cost, so storage tiers for older originals, regional CDN capacity and sharding of the post and engagement stores matter more than the API tier.

How it works, step by step

The walkthrough above, as text. Each step lights up the components named under it.

  1. When a user shares a photo, the Mobile App first asks the Upload Service for a short-lived signed upload URL. App servers only hand out permission; they never carry the image bytes.

    Components Upload Service, Mobile App, API GatewayVia start upload

  2. The app uploads the full-size original straight to the Original Store using that URL. Large uploads can resume after a dropped connection without tying up an API server.

    Components Original Store, Mobile AppVia PUT signed URL

  3. An upload-complete event on the Event Bus wakes the Image Workers, which read the original, fix its orientation and strip location metadata. Processing runs off the request path, so a slow resize never blocks the app.

    Components Image Workers, Event Bus, Original StoreVia consume

  4. The Image Workers write a fixed set of sizes, from small thumbnails to full-screen display copies, in modern formats to the Derived Image Store. Generating sizes once at upload is cheaper than resizing on every view.

    Components Derived Image Store, Image WorkersVia write sizes

  5. Each image is also checked by the Moderation Classifier before the post becomes visible. Flagged images are held for human review instead of being published.

    Components Moderation Classifier, Image WorkersVia classify

  6. The app then creates the post, and the Post Service stores the caption and media ids in the Post DB, sharded by user id so one user's posts sit together. The post is shown to others once the workers report its media ready.

    Components Post Service, Post DB, Image WorkersVia create post

  7. A post-created event reaches the Feed Fan-out Worker, which pages through the author's followers from the Follow Service. Doing this asynchronously keeps posting fast for authors with large followings.

    Components Feed Fan-out Worker, Event Bus, Post Service, Follow Service, Follow DBVia consume

  8. The worker prepends the post id to each follower's list in the Feed Cache, capped at a few hundred entries. Only ids are stored, so a deleted or edited post changes in one place.

    Components Feed Cache, Feed Fan-out WorkerVia push post id

  9. Opening the app calls the Feed Service, which reads the id list, hydrates posts from the Post Service and adds like counts from the Counter Cache. Very popular accounts are merged in at read time rather than fanned out, as in a timeline system.

    Components Feed Service, Feed Cache, Post Service, Counter CacheVia get feed

  10. Images load from the Image CDN, and the client picks the size that fits its screen, much like srcset on the web. Each size has a unique URL, so it can be cached with a long, immutable lifetime.

    Components Image CDN, Derived Image Store, Web AppVia load images

  11. A like goes to the Engagement Service, which writes it to the Engagement Store partitioned by post id and increments the count in the Counter Cache. Counts are read far more often than the list of likers, so they are kept separately.

    Components Engagement Service, Engagement Store, Counter CacheVia like / comment

  12. Engagement events also reach the Notification Service, which batches them into alerts such as "12 people liked your photo". Batching keeps a popular post from sending hundreds of pushes.

    Components Notification Service, Engagement ServiceVia consume

  13. The Search Indexer adds new users, hashtags and captions to the Search Index from the same event stream. Search can be a few seconds behind posting without anyone noticing.

    Components Search Index, Search Indexer, API GatewayVia index

Sequence diagram

The same walkthrough as a UML sequence diagram, one lane per layer or group (23 components in all), left to right in the order a request reaches them, numbered by step. A loop on a lane is a step that stays inside that group. Solid arrows are synchronous calls, dashed are asynchronous.

Photo sharing platform: sequence diagram of the walkthroughEdgeUpload PipelineClientsFeedPosts &EngagementSocial GraphDiscoverystart upload1HTTPS1PUT signed URL2consume3upload complete3read original3write sizes4classify5create post6write6media ready6consume7post created7list followers7SQL7push post id8get feed9read ids9hydrate posts9counts9load images10origin10load images10like / comment11write11increment11consume12engagement event12index13consume13search13

Key components

Clientslayer

  • Mobile App: capture, edit, upload, browse feed
  • Web App: browse profiles and feed

Edgelayer

  • API Gateway: TLS, auth, rate limits, routing
  • Image CDN: serves resized images near users

Upload Pipelinedomain

  • Derived Image Store: thumbnails and display sizes (s3)
  • Image Workers: orient, strip metadata, resize
  • Moderation Classifier: flags policy-violating images
  • Original Store: full-size originals (s3)
  • Upload Service: signed upload URLs, upload sessions

Feeddomain

  • Event Bus: upload, post, like events (kafka)
  • Feed Cache: per-user list of post ids (redis)
  • Feed Fan-out Worker: adds post ids to follower feeds
  • Feed Service: reads, merges and hydrates feed

Posts & Engagementdomain

  • Counter Cache: like and comment counts (redis)
  • Engagement Service: likes and comments
  • Engagement Store: likes/comments partitioned by post (cassandra)
  • Post DB: posts sharded by user id (postgresql)
  • Post Service: caption, media ids, visibility

Social Graphdomain

  • Follow DB: follow edges by user (postgresql)
  • Follow Service: follow, unfollow, follower lists

Discoverydomain

  • Notification Service: likes, comments, new followers
  • Search Index: users and hashtags (elasticsearch)
  • Search Indexer: indexes users, hashtags, captions

Observability

  • Observability: metrics, queue depth, error rates

Sources

Public writing this explainer draws on. Read these for what the real systems actually do.

Make it yours

Copy this diagram and its walkthrough into your own workspace, then change anything: swap Postgres for DynamoDB, add a cache, rewrite the narration. Free, and it uses no AI credits.

This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate. Real systems differ in the details. Browse the library.