Product

Product Features How to Compare Docs Screenshots Why

Start here

Getting started Download Guides Frequently asked questions

More

Security Support Roadmap About

Caching

13 answers

Keeping a copy of what does not change.

Looking for something specific

The searchable index covers all 326 answers at once and filters as you type.

103 Set up caching for static files
  1. Zones & Access, Caches tab, add one.
  2. Name it static-files, folder /var/cache/nginx/static, index memory 10m, maximum size 1g, inactive 60m.
  3. Choose it on a path that covers your static content rather than on the whole site.
cachestaticzonespeed
104 What is safe to cache and what is not?
  • Almost always: images, fonts, stylesheets, compiled scripts, downloads.
  • Often: API responses that are the same for everybody.
  • With care: whole pages for signed out visitors, keyed so a signed in visitor never gets one.
  • Never: anything that depends on who is asking, unless the cache key says who is asking.

A cached page belonging to one signed in user being served to another is a data breach, not a glitch. It is the single most common way caching goes wrong.

safe to cacheprivatecookiesdata breach
105 Check whether my cache is working

The generated log format includes $upstream_cache_status, so the access log shows HIT, MISS, BYPASS and EXPIRED per request.

sudo tail -f /var/log/nginx/access.log

A cache that never reports HIT is costing you disk and giving you nothing. The usual reason is a response header from your application telling nginx not to store it.

cache hitMISSnot workinglogs
106 Clear the cache

nginx is built with the cache purge module, so purging individual objects is available. The blunt approach of deleting the cache folder and reloading also works and is sometimes the honest answer.

purgeclear cacheflushinvalidate
107 Do the two nodes share a cache?

No. Each node caches on its own disk. A warm node and a freshly restarted node behave differently for a while, and that is normal.

shared cacheclusterper node
180 Keep serving the old copy when the backend goes down

This is the single best reason to have a cache at all. Open the site, Settings tab, Caching, tick Show advanced settings, and tick the conditions that should serve a stale copy: Backend errored, Backend timed out, and 500, 502, 503 and 504.

Now a backend falling over means visitors get yesterday's page instead of an error page. For a news site, a documentation site or a marketing site, that is the difference between a bad afternoon and an outage anybody notices.

Tick Refresh stale entries in the background too, so a visitor never waits for a refresh. They get the cached copy immediately and the fetch happens behind them.

staleproxy_cache_use_staleoutageserve oldresilience
181 See whether a response came from the cache

Open the site, Settings tab, Caching, with advanced settings shown, and tick Add an X-Cache-Status header.

Every response now carries HIT, MISS, BYPASS, EXPIRED or STALE. Look at it in the browser network tab or with curl -I.

MISS every time means something is stopping the cache, and it is usually a Set-Cookie on the response or a Cache-Control saying no. BYPASS means one of your own skip rules is firing. Leave the header on while you are tuning and turn it off afterwards if you would rather not publish it.

X-Cache-StatusHITMISScache debuggingnot caching
182 Do not cache anything for a signed in visitor

Open the site, Settings tab, Caching, and use the two boxes:

  • Skip the cache when: the cache is not read. The request goes to the backend, and the answer may still be stored.
  • Never store when: the answer is not written to the cache at all.

Put your session cookie in both. Skipping without never storing means the first signed in visitor caches their own page and everybody after them gets it, which is a data leak rather than a performance problem.

Set both. Every time.

cache bypassno cachesession cookielogged inprivate page
184 Set how long browsers keep images and scripts

Open the site, Settings tab, Static Files, Browser cache time. This is separate from the cache on the load balancer. It tells the visitor's own browser not to ask again.

A long time is right only if the file name changes when the content does, which is what a build tool with hashed file names gives you. Then a year is safe and correct.

If your files keep the same names between releases, keep this short, an hour or less. Otherwise a returning visitor is stuck on the old copy and no amount of deploying will shift it.

expiresbrowser cacheCache-Controlmax-agestale assets
185 Clear one page out of the cache without clearing the lot

Open the site, Settings tab, Caching, advanced settings shown, and tick Allow cache purging. That turns on a purge request for one address, so a page you just corrected can be refreshed without throwing away everything else.

Put it behind an access list. A purge endpoint anybody can reach is a way to make your cache useless on demand, which is a cheap way to knock a site over.

purgeclear cacheinvalidateone pagecache_purge
186 Change what makes two requests the same page

Open the site, Settings tab, Caching, advanced settings shown, Cache key.

By default the key includes the query string, so ?ref=twitter and ?ref=email are two separate cached copies of an identical page. On a site with tracking parameters flying around, that can mean thousands of copies of one page and a cache that never hits.

Take the query string out of the key for pages where it does not change the content. Do not do it for a search page, where the query string is the whole point.

proxy_cache_keyquery stringutmduplicate cachehit rate
187 Stop everybody hammering the backend when one page expires

A popular page expires, a hundred requests arrive at once, all hundred miss, and all hundred go to the backend for the same thing. That is a stampede, and it is how a cache that was helping suddenly becomes the reason a site fell over.

Open the site, Settings tab, Caching, advanced settings shown, and tick Only let one request refresh a page. One request goes through. The other ninety nine wait for it, or get the stale copy if you also turned on serving stale while refreshing.

thundering herdstampedecache lockproxy_cache_lockspike

Two fresh servers is all it takes

Ubuntu 22.04 or newer, root access, and about twenty minutes. The installer does the rest and it is safe to run twice.