Photos are the payload, thumbnails are the traffic, and both must survive losing a disk. Where does each copy live?
Photo storage should separate originals from thumbnails. Originals are large, rarely read and irreplaceable, so keep a canonical erasure-coded object; thumbnails are small, hot and rebuildable, so replicate them, cache them at the edge and address them by content or transform version.
What the interviewer is scoring
- Does the candidate separate the two objects by request count and byte volume before choosing storage for either
- Whether erasure coding and replication are matched to object size and read frequency rather than named as alternatives
- That derived data is given weaker durability on purpose, with the regeneration cost priced
- Can they explain why a content-addressed key removes the invalidation problem entirely
- Whether losing a disk is distinguished from losing a rack, a region and an operator mistake
Answer
Short answer
Store original photos and thumbnails as different workloads. The original is the durable source of truth, so keep it in object storage with strong durability and no direct public reads. Thumbnails are derived, frequently read and rebuildable, so store replicated derivatives behind a CDN using content- or version-addressed keys that avoid cache invalidation.
Two objects, two workloads, one system
Put numbers on the asymmetry, because the whole design falls out of it. Say an original is 4MB and a feed thumbnail is 20KB. A single screen of a feed pulls thirty thumbnails; the original behind any one of them is opened rarely, and most are never opened at all. So the thumbnail is a two-hundredth of the bytes and perhaps a hundred times the request count.
That is not one storage problem with two file sizes. It is a throughput problem and a request-rate problem sitting in the same product, and they want opposite things. The original wants cheap bytes at rest and does not care about latency. The thumbnail wants the lowest possible latency per request and barely registers as volume.
A photographer's shop is the closest analogy. Negatives go in a fireproof cabinet at the back and nobody browses them; prints go in the window where every passer-by looks. The analogy earns its place because it also explains the durability difference: a lost print can be made again, a lost negative cannot. It breaks at the point where the enlarger matters. Reprinting assumes the equipment and the recipe still exist, and a thumbnail pipeline whose code has moved on cannot reproduce yesterday's output byte for byte.
The original: one canonical copy, erasure-coded, never served directly
Originals are the system of record. Write once. Read seldom. Keep for ever. That profile suits erasure coding, which splits an object into data and parity fragments spread across failure domains, and reconstructs the object from any sufficient subset. A 6-plus-3 scheme stores 1.5 bytes for every byte of data and tolerates the loss of any three fragments. Three-way replication tolerates two losses and stores three bytes per byte. At photo-library scale the difference between 1.5x and 3x is the storage bill.
You pay for it on the read. Reconstructing an object requires fetching several fragments from several devices, which costs more requests and higher latency than reading one replica. For a 4MB object read occasionally that is a fine trade. For a 20KB object read constantly it is a bad one, because the per-request overhead dwarfs the payload. This is the reasoning that should drive the answer, rather than a preference for one scheme over the other.
Keep the original off the public read path. Users receive a rendered derivative, so the only readers of the original are your own render pipeline and the rare full-resolution download, which can go through a signed URL with its own expiry. That also means an original can live in a colder tier with a retrieval delay your feed would never tolerate.
The thumbnail: replicated, cached, and addressed by its content
Thumbnails are derived. That single fact buys freedom the original never has. You can store them with less durability, evict them, and lose a whole tier of them without losing anything a user owns, as long as the pipeline that made them can be run again.
Store them small, replicated rather than coded, and front them with a CDN. Then name them by the hash of their own bytes, or by the hash of the original plus the transform parameters. The key now changes whenever the content changes. That removes invalidation from the design rather than solving it. The URL for a given rendering is immutable, so it can carry a very long cache lifetime at the edge and in the browser, and a new rendering is a new URL that no cache has ever seen.
# Content-addressed derivative keys: the transform is part of the name,
# so no cache entry ever has to be purged - it is simply never asked for again.
originals/8f14e45fceea167a5a36dedd4bea2543 # canonical, erasure-coded
derived/8f14e45f.../w320-h320-q80-v3.webp # v3 is the renderer version
The v3 on the last line is the part worth defending in an interview. Bake the renderer's version into the key and a pipeline change becomes a new namespace rather than a fleet-wide purge. Old objects age out on their own schedule while new requests miss cleanly and rebuild.
Losing a disk is the easy failure
The question says a disk. Every storage system already handles a disk. Replication and erasure coding both survive one without anybody being woken up. The failures that shape a design are the larger ones, and a good answer walks up the ladder without being asked.
- A disk or a node. Handled by the redundancy scheme itself. The system rebuilds in the background; the interesting metric is how long a rebuild takes, because that window is when a second failure becomes a real loss.
- A rack or an availability zone. Only survivable if fragments or replicas were placed across those domains deliberately. Three replicas on three disks in one rack is a design that reads as durable and is not.
- A region. Requires a second copy of the originals somewhere else, which is a cost decision, and asymmetric: derivatives do not need copying because they can be rebuilt from whichever copy of the original survived.
- An operator or a bug. Redundancy replicates a bad delete faithfully to every copy. Versioning, or a delete marker with a retention window, is what covers this, and it is the one people forget.
Regenerating everything at once is the failure mode you designed in
"Thumbnails can be rebuilt" is true and it is load-bearing, so it deserves a cost. Suppose the derivative tier is lost, or a renderer bug forces a new version for every image. Every feed request now misses, and each miss becomes a read of a 4MB original plus a render. The traffic your CDN was absorbing lands on the pipeline at full request rate, multiplied by two hundred in bytes.
So the rebuild has to be a controlled operation rather than an emergent one. Bound the renderer's concurrency. Shed rather than queue without limit. Keep the previous version's derivatives readable while the new ones are being made, which the versioned key gives you for free. And precompute the sizes the feed actually requests before you make them reachable, so the first user through the door is not paying for the migration.
Derived data is not exempt from design; it is exempt from durability. Everything you save by treating thumbnails as disposable, you owe back on the day you have to make them all again at once.
© 2026 Preptima. Originally published at preptima.com.
Likely follow-ups
- A code change makes every existing thumbnail wrong. What is your plan, and what does the renderer see in the first minute?
- Why is a 6-plus-3 erasure code a poor choice for 20KB objects when it is a good one for 4MB objects?
- If two users upload the same photograph, what does content addressing do to your delete-my-data guarantee?
- How do you serve a thumbnail whose original has been erasure-coded into a region that is currently unreachable?
Related questions
- A two-hour film must start playing within two seconds on a phone on 4G. What has to exist before the play button works?hardAlso on cdn6 min
- Your origin is in one region and readers are worldwide. What do you cache, and what happens the moment you must invalidate it?hardAlso on cdn6 min
- Design the asset delivery and deploy strategy for a large single-page app. What happens to a user who has the tab open when you ship?hardAlso on cdn6 min
- Users upload files up to 5GB and you must not proxy them through your API servers. How does the upload actually work?hardAlso on object-storage5 min