Caching Layers
This page explains the cache key, lifetime, and invalidation of each of the four layers an image passes through: browser, Cloudflare Worker, Nginx, and local cache files.
The Four Layers
| Layer | Cache key | Lifetime | Configured in |
|---|---|---|---|
| Browser | Full URL | 7 days (Cache-Control: public, max-age=604800 plus Expires) |
GetFromPath headers; Nginx adds the same value |
| Cloudflare Worker | Origin URL plus full query string | 7 days (max-age=604800) |
worker/index.js |
| Nginx | Default proxy_cache key (includes query) |
7 days for 200 / 301 / 302 / 304, 1 minute otherwise; evicted after 30 days without access; 2 GB cap | config/nginx/nodes.conf |
| Local cache file | Filename built from parameters (below) | No expiry, never cleaned automatically | GetFileCachePath() |
Local Cache File Naming
Cache files live in storage/image/cache/, mirroring upload/. The original extension is stripped and the parameters are appended:
| Parameters | Filename pattern |
|---|---|
s present |
{name}_{s}_{q}_{b}_{B}.{t} |
w and h |
{name}_{w}_{h}_{q}_{b}_{B}.{t} |
Only w |
{name}_{w}_auto_{q}_{b}_{B}.{t} |
Only h |
{name}_auto_{h}_{q}_{b}_{B}.{t} |
| None | {name}_auto_auto_{q}_{b}_{B}.{t} |
Each segment uses the raw request string, unnormalized: ?s=480&t=avif yields {name}_480___1.avif (q and b are empty, B defaults to 1), while ?s=480&t=avif&q=50 produces identical output but a separate cache file.
Lookup Order
graph LR
Req[Request] --> B{Browser fresh?}
B -- No --> W{Worker hit?}
W -- No --> N{Nginx hit?}
N -- No --> L{Local cache file exists?}
L -- No --> V[libvips transform and write cache file]
Requests that bypass the Worker go from the browser straight to Nginx. .pdf, .svg, and o=1 never write a local cache file and are cached only by the first three layers.
Invalidation
The code has no cache purge. Deleting an original only moves the file in upload/ to the trash; transformed results in cache/ remain, and GetFromPath checks the cache file before the original, so existing size variants of a deleted image keep being served. To take an image down immediately, delete the matching files under storage/image/cache/ and purge both the Nginx cache at /var/cache/nginx/images and the Cloudflare cache.