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


Now read this

Evolving CRUD (part 2)

Serving content at scale without complexity Command Querying Responsibility Segregation Martin Fowler and Udi Dahan have in the past described this approach at length. This is obviously not a new concept and what follows is only a... Continue →