Proxy cache

Hey,

I need a little bit of help in understanding how proxy cache works in
Nginx. I’ve already managed to set up the cache and it works. Now I’m
tweaking it and I’m having some trouble with the proxy_cache_valid
directive. How does it work exactly? In some recent changelog I found
that the cache now respects “Expires” and “Cache-Control” headers. How
does this relate to proxy_cache_valid? Imagine the following
scenarios:

  1. proxy_cache_valid is set to 1h and upstream’s response is valid for
    2h.
  2. proxy_cache_valid is set to 2h and upstream’s response is valid for
    1h.
  3. proxy_cache_valid is set to 1h and upstream’s response doesn’t
    contain any caching hints.

For how long will Nginx cache the response in each of the above
scenarios?

Does Nginx respect “Pragma: no-cache” header?

Which “Cache-Control” header directives (see
HTTP/1.1: Header Field Definitions) does
Nginx respect?

What happens if the client sends “If-Modified-Since” header?

How does Nginx deal with “Vary” header?

That’s a lot of questions, sorry for that :). Answer to any of them
will be appreciated :). If someone has the time to answer, I’ll try to
spend some time and update the Wiki.

Regards,

On Tue, May 19, 2009 at 02:57:23PM +0200, Micha?? Jaszczyk wrote:

  1. proxy_cache_valid is set to 1h and upstream’s response is valid for 2h.
    nginx will cache for 2h.
  1. proxy_cache_valid is set to 2h and upstream’s response is valid for 1h.

nginx will cache for 1h.

  1. proxy_cache_valid is set to 1h and upstream’s response doesn’t
    contain any caching hints.

nginx will cache for 1h.

For how long will Nginx cache the response in each of the above scenarios?

Does Nginx respect “Pragma: no-cache” header?

No. I belive no one browser respects this header, since it’s client side
header only.

Which “Cache-Control” header directives (see
HTTP/1.1: Header Field Definitions) does
Nginx respect?

“no-cache”, “max-age=0”, “max-age=NNN”.
Probably “no-store” should be added.

What happens if the client sends “If-Modified-Since” header?

This header does not send to backend, however, nginx may responses 304.

How does Nginx deal with “Vary” header?

Not at all.

nginx will cache for 1h.

This just means that upstream’s caching instructions are more
important than proxy_cache_valid, right?

What happens if the client sends “If-Modified-Since” header?

This header does not send to backend, however, nginx may responses 304.

I’m not sure if I understand. Let’s imagine some scenarios (I-M-S
stands for If-Modified-Since, L-M stands for Last-Modified):

  1. Client sends I-M-S, Nginx has response in cache, cached response
    has L-M < I-M-S, Nginx sends 304.

  2. Client sends I-M-S, Nginx has response in cache, cached response
    has L-M > I-M-S, Nginx serves response from cache.

  3. Client sends I-M-S, Nginx doesn’t have response in cache, sends
    request to upstream, upstream’s L-M < I-M-S, Nginx stores response in
    cache and sends 304.

  4. Client sends I-M-S, Nginx doesn’t have response in cache, sends
    request to upstream, upstream’s L-M > I-M-S, Nginx stores response in
    cache and sends response from upstream.

Am I right?

Regards,

So,

proxy_ignore_headers X-Accel-Expires Expires Cache-Control;

Does work, but i lost quite some time until i realised that nginx sets
an expiration time at the moment when a response is cached, restarting
nginx afterwards with other configuration settings won’t change
anything.

So, whenever your playing with proxy_ignore_headers, proxy_cache_valid
remember to empty your cache dir :wink:

On Tue, May 19, 2009 at 03:39:59PM +0200, Micha?? Jaszczyk wrote:

nginx will cache for 1h.

This just means that upstream’s caching instructions are more
important than proxy_cache_valid, right?

Yes, the order is

X-Accel-Expires
Expires/Cache-Control
proxy_cache_valid

However, you may ignore the headers using

proxy_ignore_headers X-Accel-Expires Expires Cache-Control;

What happens if the client sends “If-Modified-Since” header?

This header does not send to backend, however, nginx may responses 304.

I’m not sure if I understand. Let’s imagine some scenarios (I-M-S
stands for If-Modified-Since, L-M stands for Last-Modified):

  1. Client sends I-M-S, Nginx has response in cache, cached response
    has L-M < I-M-S, Nginx sends 304.

Yes. Small note, by default nginx sends 304 only if L-M == I-M-S.
Controlled by if_modified_since [off|exact|before] directive

  1. Client sends I-M-S, Nginx has response in cache, cached response
    has L-M > I-M-S, Nginx serves response from cache.

Yes.

  1. Client sends I-M-S, Nginx doesn’t have response in cache, sends
    request to upstream, upstream’s L-M < I-M-S, Nginx stores response in
    cache and sends 304.

Yes.

  1. Client sends I-M-S, Nginx doesn’t have response in cache, sends
    request to upstream, upstream’s L-M > I-M-S, Nginx stores response in
    cache and sends response from upstream.

Yes.