Immutable Cache-Control for Generated Placeholder Images
Generated placeholder images with stable URLs can carry immutable Cache-Control headers, eliminating revalidation round-trips and cutting CDN bandwidth costs.
Cache-Control: public, max-age=31536000, immutable tells browsers and CDNs to cache a resource for one year and never revalidate it — no conditional GET, no ETag check, no If-Modified-Since round-trip. For generated placeholder images whose output is fully determined by their URL, this header is appropriate and performant.
The immutable directive was designed for content-addressed assets that will never change at a given URL. Deterministic placeholder images qualify: the same URL always produces the same pixels. Applying immutable cache headers to placeholder URLs collapses repeated fetches into zero-latency memory or disk cache hits.
Cache-Control basics
max-age, immutable, and must-revalidate — what each directive does
max-age=N tells the browser and shared caches to treat the response as fresh for N seconds. After N seconds, the resource is stale and requires revalidation — a conditional GET with If-None-Match or If-Modified-Since. The server responds with 304 Not Modified if the resource has not changed, or with a new 200 response if it has.
immutable is an extension directive that tells the browser the resource will never change before max-age expires. With immutable, the browser skips the revalidation request entirely. This eliminates one round-trip per stale resource per page load — meaningful on pages with many placeholder images.
must-revalidate is the opposite: it forces the browser to check with the server before using a stale resource, even if offline or in an HTTP/2 push scenario. For placeholder images that never change, must-revalidate is the wrong directive. Do not combine it with immutable.
Immutable suitability
Deterministic placeholder URLs qualify for immutable caching
The contract for immutable is strict: you must never change the content at a given URL. If you do, browsers that have cached the old response will never fetch the update during the max-age window. For content-addressed assets where the URL encodes the content — like code bundles with a hash — this is safe.
Placeholder images from fallback.pics are deterministic: the URL fully describes the output. A request to /api/v1/400x300/7C3AED/FFFFFF?text=Product always produces the same SVG or raster image. The URL is its own cache key. Applying immutable cache headers to these URLs is safe by design.
This is different from user-generated or database-backed images where the content at a URL can be updated. Those images should use versioned URLs or short max-age values, not immutable.
CDN behavior
How CDN edge nodes handle immutable cache headers
CDNs like Cloudflare, Fastly, and CloudFront respect Cache-Control headers by default. When a response carries public, max-age=31536000, immutable and the CDN has not yet cached it, the CDN fetches from the origin once and stores the response. Subsequent requests for the same URL are served from the CDN edge, with zero origin fetches for one year.
Cloudflare adds its own CDN-Cache-Control layer. If you want the CDN to cache the image even longer than the browser's max-age, add CDN-Cache-Control: max-age=31536000 separately. Cloudflare evaluates both headers and uses the most specific one that applies to the CDN edge.
Some CDNs strip or ignore Cache-Control headers unless explicitly configured to respect them. Check your CDN's documentation for Edge Cache TTL settings. Cloudflare's default caching rules override Cache-Control for some status codes; verify that 200 responses with your Content-Type are cached according to the response headers.
Browser cache tiers
Memory cache, disk cache, and the back/forward cache
Browsers maintain multiple cache tiers. Memory cache holds recently fetched resources for the current session; disk cache persists across sessions up to the max-age limit. Immutable resources that fit in memory cache are served with zero network activity — the browser does not even touch the disk.
The back/forward cache (bfcache) in modern browsers preserves a snapshot of rendered pages so navigation feels instant. Immutable cached images remain valid in bfcache because there is no revalidation needed. Pages heavy with placeholder images benefit from this because no image re-fetching occurs on back-navigation.
Cache busting
Invalidating immutable placeholders when content must change
Immutable cache headers commit you to never changing the response at a given URL. The only way to serve updated content is to use a new URL. For placeholder images, this is rarely necessary — the point is that they are stable by design.
If you do need to change a placeholder — switching a brand color or updating a text label — change the URL parameters. The new URL is a new cache key, and browsers and CDNs treat it as an uncached resource. The old URL remains cached for up to a year in clients that have seen it, which is usually fine for placeholder content.
<!-- Old URL stays cached, new URL is fresh -->
<!-- Old: purple background -->
<img src="https://fallback.pics/api/v1/400x300/7C3AED/FFFFFF?text=Product" />
<!-- New: updated brand blue background -->
<img src="https://fallback.pics/api/v1/400x300/3B82F6/FFFFFF?text=Product" /> Measuring impact
Quantifying the revalidation round-trip savings
Open DevTools Network panel and filter by Img. Reload the page with a cold cache (Ctrl+Shift+R) and note all image fetch times. Then reload normally and compare. Without immutable, stale images trigger conditional GETs — you see 304 responses with latency equal to the round-trip time to the origin or CDN edge.
With immutable Cache-Control headers, those 304 responses disappear. The browser reads the resources from disk or memory cache with 0ms latency. On a page with 30 placeholder images and a 60ms round-trip to the server, the difference is 1.8 seconds of eliminated round-trips per page load.
# API docs
https://fallback.pics/docs/
https://fallback.pics/placeholder-image-api/
# Related posts
https://fallback.pics/blog/cache-control-placeholder-images-cdn-browser/
https://fallback.pics/blog/cloudflare-cdn-cache-generated-images/ Key takeaways
What to standardize before shipping
- Use Cache-Control: public, max-age=31536000, immutable for generated placeholder images whose URLs encode the content.
- The immutable directive eliminates revalidation round-trips, saving latency proportional to the number of placeholders on the page.
- Never change the response at an immutable URL — change the URL instead when content needs to update.
- CDN edge caching requires both browser Cache-Control headers and correct CDN configuration to work end-to-end.
- Measure revalidation savings in DevTools Network panel by comparing cold and warm cache load times.
Production fallback layer
Use fallback.pics anywhere an image URL is accepted.
Start with one deterministic URL and standardize fallback behavior across your design system.