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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Related walkthroughs
- Video sharing platform (YouTube-style)How a video platform takes resumable uploads, encodes segments in parallel into several renditions, and serves them via a CDN with adaptive bitrate.
- Content delivery networkHow a CDN routes users to a nearby PoP, serves cached copies, shields the origin with a regional tier, and purges content worldwide in seconds.
- Music streaming serviceHow a music streaming service pre-encodes tracks into encrypted segments, checks rights before playback, and turns play events into royalties.
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.