Skip to content

Cache ​

Every requested file is kept on disk. Later requests are served from disk without touching the storage.

The “Cache” section of a route's row: purge and warm

The “Cache” section of a route's row: purge and warm · 26/09/2026

What the cache decides for every requestRequestGET or HEADHITanswers immediatelyFresh copy?in cache and not expiredStoragesigned requestMISS200 · downloads, saves and sendsREVALIDATED304 · the copy is still validSTALEstorage down · expired copy404missing (remembered 60 s)502credentials or storageyesno

What X-Cache says ​

ValueMeaning
HITServed from a fresh copy in cache.
MISSNot in cache: downloaded from the storage and saved while being sent.
REVALIDATEDExpired copy, but the storage confirmed (304) it is still valid.
STALEExpired copy served because the storage does not answer (see below).
BYPASSPassed to the storage without using or filling the cache (HEAD or Range requests with no cached copy, files that are too large).
(absent)Response with no cache outcome: 404s generated by the gateway, errors.

The cache policy ​

The panel uses a standard policy:

ParameterValueWhat it does
ttl1 hourHow long a copy is fresh. Then it is revalidated with the storage.
ttl_not_found60 secondsBriefly remembers that a file is missing (negative cache), so a repeated typo does not hammer the storage.
serve_stale_on_error24 hoursIf the storage does not answer, an expired copy can be served up to this limit (STALE).
query_keysnoneNo query parameter counts: ?v=2 and ?v=3 are the same thing.

To change these values, edit the configuration by hand (see config.yaml); the panel does not expose them yet.

Useful behavior to know ​

  • One request per object. With many visitors on the same file not yet in cache, only one goes to the storage; the others wait up to 5 seconds and then, if needed, go to the storage too without cache.
  • Streaming. Files are not loaded in RAM. If the visitor disconnects the download continues to complete the cache.
  • Space limit (LRU). Above OTR_CACHE_MAX_BYTES (default 10 GiB) the least used copies are removed.
  • Large files. Above OTR_CACHE_MAX_OBJECT_BYTES (default 1 GiB) the file goes to the storage without cache.
  • Isolation. The cache is separate per route: the same file served by two domains has two copies.
  • HTTP headers. ETag, If-None-Match, If-Modified-Since, Range, If-Range are handled; the storage's x-amz-* headers never reach the visitor.
  • Errors. A storage 403 AccessDenied for a missing file becomes 404; wrong credentials give 502 and are never cached.

Emptying and warming from the panel ​

From Routes, expand a route's row: in the Cache section you find three actions (the routes:write scope is required).

ActionWhat it does
Purge fileDeletes the copy of a single file (type its name, e.g. boat.jpg): the next request reads it again from the storage. It tells you whether the file was in cache.
Purge allEmpties the route's cache with one click and a confirmation. Nothing is deleted from disk: it increases the route's cache_generation, so old copies become unreachable and the LRU removes them.
WarmList up to 200 files, one per line: the node requests them by itself, one at a time, so the first visit is already a HIT. For each file you see status, X-Cache, bytes and time. Warming stops after 2 minutes; remaining files are reported as not run.

If the route has images on the fly, Purge file removes only the original: variants expire by themselves or are removed with Purge all. Purging does not delete the file from the storage nor from any caches in front of the node (CDN, browser): those have their own timing.

In a hand-written configuration the same effect is obtained by increasing a destination's cache_generation.

Known limits ​

  • HEAD and Range without a cached copy go to the storage without filling it: the first access to a "chunked" video does not cache it.
  • There is no automatic index.html for folders.
  • Warming downloads each file in full: with very large files (up to OTR_CACHE_MAX_OBJECT_BYTES) it can take time.

Rilasciato con licenza MIT o Apache-2.0, a scelta.