I run imgproxy on my server and am using a worker to detect if the browser supports webp format and serve the correct image format for the browser requesting the image.
The image is supposed to be cached on Cloudflare forever (cacheTtl 1 year) if the image was fetched successfully. From the second fetch, cf-cache-status shows HIT as expected. However, the cache seems to expire after a few hours (cf-cache-status: MISS) instead of the 365 days specified.
The worker runs on a subdomain that I configured with the DNS entry: CNAME img @ proxied:true
This is my worker:
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
/**
* Fetch and log a request
* @param {Request} request
*/
async function handleRequest(request) {
// Parse request URL to get access to query string
let url = new URL(request.url)
const imageSrc = url.searchParams.get("src")
if (!imageSrc) return new Response('Missing "src" value', { status: 400 })
let imageWidth = url.searchParams.get("width");
let imageHeight = url.searchParams.get("height");
// Round up height/width to steps of 100 if no exact dimensions provided
if (imageWidth && !imageHeight) imageWidth = Math.ceil(imageWidth / 100)*100;
else if (imageHeight && !imageWidth) imageHeight = Math.ceil(imageHeight / 100)*100;
// Your Worker is responsible for automatic format negotiation. Check the Accept header.
const accept = request.headers.get("Accept");
let supportsWebp = false
if (/image\/webp/.test(accept)) {
supportsWebp = true
}
const imageURL = 'https://myimgproxyinstance.tld/preset:default/gravity:sm/resize:fill'
+ (imageWidth ? ':'+imageWidth : '')
+ (imageHeight ? ':'+imageHeight : '')
+ (supportsWebp ? '/f:webp' : '')
+ '/' + imageSrc
const response = await fetch(imageURL, {
cf: {
cacheTtlByStatus: { "200-299": 31536000, 404: 1, "500-599": 0 },
cacheEverything: true,
}
});
return new Response(response.body, { headers: response.headers });
}
The cache TTL is a maximum time not a minimum time. It can and will be evicted from cache at any time for a number of reasons (not enough hits, limited space, etc).
You should not rely on this to be exactly what you set but instead be up to what you set.
This is a follow-up to my last post that was auto-closed before I could reply, but the reply I received did not answer my question. When the edge cache is set to 1 year, it should not show cf-cache-status “MISS” in all cases after just one day. I am now also getting “cf-cache-status:EXPIRED” on some images that are supposed to be cached for one year and the “expires” header is always set to one hour.
About the expires header I am not sure, I don’t think Cloudflare sets it (unless you manually specify end user device caching rules), so it might come from the origin directly. Do check that.
Workers run with each request, regardless, you can’t cache their response (you can cache the origin’s response, with the Cache API and the normal caching from Cloudflare (albeit less controllable).