Nginx by examples: caching

Nginx offers out of the box very efficient caching support where

As usual the setup is fairly trivial:

server {
	proxy_cache_path /tmp/nginx-cache levels=1:2 
	  keys_zone=api_cache:10m max_size=10g inactive=60m;
	location /api {
		proxy_cache api_cache;
		# we allow only 1 req per URI to hit origin 
		# in case of a cache miss
		proxy_cache_lock on;
		# we add the X-Proxy-Cache header to our response to the client
		add_header X-Proxy-Cache $upstream_cache_status; 

In this example

By default Nginx will respect the cache headers are returned by the downstream server and the preferred way to manage the caching of replies is to set a Cache-Control header in the reply

Force cache

In some cases we can’t modify our downstream servers to serve appropriate Cache-Control headers

In these circumstances we can force some generic caching policies as follows

location /api {
	proxy_cache api_cache;
	# we ask Nginx to ignore the Cache-Control header
	proxy_ignore_headers Cache-Control;
	# we cache any 200 or 302 response for up to 10 minutes
	proxy_cache_valid 200 302 10m;
	# any 404 response is cached for 1 minute
	proxy_cache_valid 404      1m;



Cookies and cache

For obvious reasons by default Nginx will not cache requests where the Set-Cookie header is set.

Unfortunately many server side technologies (PHP, Java etc) create a cookie based session with each request by default thus preventing Nginx from caching pretty much any request even if the Cache-Control header is set

In these circumstances it’s useful to setup a different cache punching header to send with not cacheable responses

# we ignore the Set-Cookie header
proxy_ignore_headers Set-Cookie;

# we hit origin every time a X-No-Cache custom header is set
proxy_no_cache $http_x_no_cache 

Invalidating the cache

The opensource version of Nginx doesn’t come out of the box with many ways to invalidate the cache except proxy_cache_bypass

# Trigger a synchronous cache update 
# when a specific `X-No-Cache` header 
# or if a `nocache` GET parameter are set
proxy_cache_bypass $http_x_no_cache $arg_nocache;

Unfortunately proxy_cache_bypass does not update the internal cache reference if a 404 response code is returned

We have a few options


comments powered by Disqus

Subscribe to my newsletter