NGINX Content Caching


NGINX Content Caching

This chapter describes how to enable and configure caching responses received from proxied servers. When caching is enabled NGINX saves responses in the cache on the disk and uses them to respond to clients without proxying the requests.

Enabling the Cache of Responses

To enable caching configure the path to the cache and other parameters using the proxy_cache_path directive. Then place the proxy_cache directive in the context where you want caching to be enabled:

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m;

    server {
        proxy_cache one;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

Note that the proxy_cache_path directive can be specified only on the http level. It has two mandatory parameters: the path on the file system where cached responses will be stored, and the name and size of the shared memory zone defined by the keys_zone parameter. The same name is specified in the proxy_cache directive.

The shared memory zone is used to store meta information on cached items. However, its size does not limit the total size of the cached responses. Cached responses themselves are stored with the copy of the meta information in specific files on the file system. You can limit the size of this file storage with the max_size parameter. However, the actual size of the file storage can temporarily exceed this until a process called cache manager checks the cache size and removes the least recently used cached responses and their metadata.

Caching Processes

There are two additional NGINX processes involved in caching, the cache loader and the cache manager.

The cache manager is activated periodically to check the state of the cache file storage. In particular, it removes the least recently used data when the size of the file storage exceeds the max_size parameter.

The cache loader is activated only once, right after NGINX starts. It loads the meta information about the previously cached data into the shared memory zone. Loading the whole cache at once may consume a considerable amount of resources and slow nginx’s performance during the first minutes. This is why the cache loader works in iterations configured with parameters of the proxy_cache_path directive.

Each iteration lasts no longer than a loader_threshold value specified in milliseconds (by default, 200). During one iteration the cache loader can load no more than the loader_files items secified (by default, 100). A pause between iterations is set with loader_sleeps in milliseconds (by default, 50). For example, these parameters can be modified to speed up loading of the cache meta data:

proxy_cache_path /data/nginx/cache keys_zone=one:10m
                 loader_threshold=300 loader_files=200;

Specifying Which Requests to Cache

By default, NGINX caches all responses that have the GET and HEAD methods the first time such responses are received from a proxied server. As a key identifier of a request NGINX uses the request string. Whenever two requests have the same key they are considered equal and the same cached response is sent to the client. The proxy_cache_key directive defines the way the key is calculated for a request and can be changed on the location, server, or http level:

proxy_cache_key "$host$request_uri$cookie_user";

It is possible to increase the minimum number of times a request with the same key should be cached by using the proxy_cache_min_uses directive:

proxy_cache_min_uses 5;

It is also possible to specify additional HTTP methods of the requests to cache:

proxy_cache_methods GET HEAD POST;

This setting enables caching of responses for requests that have the GET, HEAD, or POST method.

Limiting or Bypassing Caching

By default, the time which a response is cached isn’t limited. When the cache file storage is exceeded it will be removed if it has been used less than other cached items. Otherwise, the response can be kept in the cache indefinitely.

You can limit the time which responses with specific status codes are considered valid, by using the proxy_cache_valid directive:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

In this example the responses with the 200 and 302 code will be valid in the cache for 10 minutes, and the responses with the 404 code will be valid for 1 minute. To set the storage time limit applied all status codes, specify any in the first parameter:

proxy_cache_valid any 5m;

To define conditions when the response is not taken from the cache (even if it may exist in the cache) use the proxy_cache_bypass directive. Keep in mind that no conditions are specified by default. The directive may have one or several parameters, each may consist of a number of variables. If at least one parameter is not empty and does not equal “0”, NGINX will not look up the response in the cache. For example:

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

To define conditions where the response is not saved in the cache at all, use the proxy_no_cache directives. The conditions are specified by the same rules as for proxy_cache_bypass:

proxy_no_cache $http_pragma $http_authorization;

Combined Configuration Example

The configuration sample below combines some of the different caching options described above.

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m
                     loader_threshold=300 loader_files=200
                     max_size=200m;

    server {
        listen 8080;
        proxy_cache one;

        location / {
            proxy_pass http://backend1;
        }

        location /some/path {
            proxy_cache_valid any   1m;
            proxy_cache_min_uses 3;
            proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
            proxy_pass http://backend2;
        }
    }
}

This example defines a virtual server with two locations that use the same cache but with different settings.

It is assumed that responses from the backend1 server rarely change and can be cached the first time a request is received and held for as long as possible.

By contrast, responses from the backend2 server are highly volatile, and therefore are cached only after three occurrences of the same request and held for one minute. Moreover, if a request satisfies the conditions of the proxy_cache_bypass directive, the cache will not be searched for the response at all and NGINX will immediately pass the request to the backend.