call(back)

Design Image Upload and Serving for Pins

Design the architecture for uploading and storing images for pins: hundreds of millions of users saving image-heavy content, processed into the sizes the product needs and served globally with low latency.

Scope: upload, dedup, processing into variants, global serving, and the pin-creation flow — not the image ML. Assume ~50M new images/day at ~1 MB, while serving is orders of magnitude larger (feeds show dozens of images per page at tens of thousands of QPS → millions of image requests per second), so the design is about the CDN and the variants, not the upload.

Cover: how bytes get in without transiting your API tier, dedup when the same image is saved by a million users, cache-friendly URLs, and what the pin row shows while processing is still running.

Hints

Hint 1

The API tier should never proxy image bytes: hand the client a presigned URL and let it PUT straight to object storage; an upload-complete event drives everything else asynchronously.

Hint 2

Content-address everything: dedup by byte hash so a million saves store one image, and make URLs immutable (/i/{sig}/{variant}.jpg) so the CDN can cache forever with no stale-cache story.

Hint 3

The pin must exist before processing finishes. Create it in a 'processing' state and flip to 'ready' — and decide which readers filter on that state.

Asked at