How it works...

NGINX internally tracks the status of the request ($upstream_cache_status), so by exposing it as a header, we can now see it from the client side. If we use Google DevTools or a utility such as httpstat to see the headers, you should see an output like this:

httpstat http://proxy.nginxcookbook.com/ 
 
HTTP/1.1 200 OK 
Server: nginx/1.11.2 
Date: Sun, 09 Oct 2016 12:18:54 GMT 
Content-Type: text/html; charset=UTF-8 
Transfer-Encoding: chunked 
Connection: keep-alive 
Vary: Accept-Encoding 
X-Powered-By: PHP/7.0.12 
X-Cache-Status: HIT 

We can see by the X-Cache-Status header that the request was a hit, meaning it was served from the cache not the backend. Other than the basic hit and miss, there are also a number of other statuses which could be returned:

Status

Meaning

HIT The request was a hit and therefore served from cache
MISS The request wasn't found in cache and therefore had to be requested from the backend server
BYPASS The request was served from the backend server, as NGINX was explicitly told to bypass the cache for the request
EXPIRED The request had expired in cache, so NGINX had to get a new copy from the backend server
STALE NGINX couldn't talk to the backend server, but instead has been told to serve stale content
UPDATING NGINX is currently awaiting an updated copy from the backend server, but has also been told to serve stale content in the interim

REVALUATED

This relies on the use of proxy_cache_revalidate being enabled and checks the cache control headers from the backend server to determine if the content has expired