Video & media
Image CDN - resize on the fly, or store every size
Cache keys, on-demand transforms, and the tail that never hits cache
What this board gets wrong on purpose
The tension
Transforms are computed on demand, so the variant a designer invents on Tuesday exists on Tuesday with no backfill - and every distinct URL is a new cache key, a new AVIF encode at 250 ms of CPU, and a new object to store. The signing service is therefore the only thing between this design and an unbounded bill, which means an availability problem in a tiny stateless service becomes a cost problem in the largest one. Pre-generating instead bounds the spend at 36 variants per master, and buys that bound with storage for the 80 percent of variants nobody ever requests and a re-generation campaign every time the design system changes a breakpoint. The board also admits a third cost neither strategy fixes: 70 percent of distinct URLs are requested once a week, so they miss on arrival, pay full transform price, get cached, and are evicted before a second request ever comes.
1. Requirements
One master image in, the right bytes out for a phone, a laptop and a retina display, in the best format each of them can decode - without the people writing the HTML having to think about any of it.
Functional
- Store one immutable master per image and serve derived sizes from it.
- Serve a width-appropriate variant to any device, driven by the srcset the publishing app emits.
- Negotiate format: AVIF where supported, WebP where not, JPEG as the floor.
- Support a named set of transforms - crop, fit, quality - and reject anything outside it.
- Invalidate an edited image everywhere within seconds.
- Report, per publisher, how much egress and how much transform CPU their images cost.
Non-functional
- Edge cache hit ratio above 95 percent. This is the top-line metric: everything else on the board is what happens in the 4 percent.
- p95 latency 30 ms on a hit, 400 ms on a cold transform. A cold AVIF encode is 250 ms of CPU and there is no way around that.
- Availability 99.99 percent - an image service that is down makes every page on every customer site look broken, which is a worse perception than an outage of the site itself.
- The number of distinct cache keys must be BOUNDED and countable. An unbounded key space is an unbounded bill.
- A variant must never be served for the wrong image. Cache-key collisions here are a content-correctness bug that looks like a security incident.
Questions to ask before designing this
- Who controls the URLs - us, or the customer? If a customer can write any parameter combination they like, the transform fleet is sized by their imagination and not by our traffic.
- How many distinct widths does the design system ACTUALLY use? Six named breakpoints is a bounded problem; continuous width parameters is an unbounded one, and everybody says six until you measure.
- What is the edit rate on published images? If images are effectively immutable, version the key and never purge. If they change hourly, the purge path is the hard part of the system.
- Is there a long tail, and how long? 70 percent of URLs requested once a week means most transforms never amortise and the cache hit ratio flatters you.
- Do we serve user-uploaded images to the public? Then a decode bomb - a 40,000 by 40,000 pixel PNG that expands to gigabytes in memory - is a denial of service, and limits belong in the requirements rather than in an incident review.
- Is animation in scope? An animated AVIF is two orders of magnitude more expensive to encode than a still, and it will arrive through the same URL shape.
The rest of this board
Available on Tier Slate
This page publishes the question. The answer — 5 more written pages, an 11-step narrated walkthrough and a 5-table schema — is the board itself, and it opens in Tierslate.
- 5written pages
- 11walkthrough steps
- 5tables34 columns
5 pages behind this one
- Capacity estimation
- Storage estimation
- Availability
- How it works
- Deployment plan
More boards
Upload, transcode, deliver - and pay for the bandwidth.