# Nginx http proxy caching

**URL:** <https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848>\
**Category:** NGINX\
**Created:** [January 19, 2010, 6:54am UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848 "2010-01-19T06:54:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [January 19, 2010, 6:54am UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/1 "2010-01-19T06:54:25Z")

</div>

Hi,  
Is there developer documentation on how http caching works in nginx? I’m  
seeing weird caching behavior where it’s caching responses with  
Cache-Control: private headers.  
Does nginx obey all caching headers correctly? Also, is there a way to  
override the caching headers for certain requests only?

As I’ve asked in another thread, I’m also trying to understand how I can  
enable/disable caching per request based on a cookie or a header set by  
upstream server. I’ve not found an answer to it yet. Any help is much  
appreciated.

Thanks,

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 10, 2010, 9:16pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/2 "2010-05-10T21:16:04Z")

</div>

On Mon, May 10, 2010 at 03:02:09PM -0400, Jim Ursetto wrote:

> nginx to not use the proxy cache while still allowing  
> the browser to cache (for example,  
> `Cache-control: max-age=3600, private`). You can only  
> disable the proxy cache in the configuration file based  
> on the current Location. I don’t really understand this  
> behavior; I think private should be honored.

You are right, “private” should be ignored.  
However, you may say nginx “X-Accel-Expires: 0” to not cache such  
responses. You may say different cache times for nginx and  
browsers/transit proxies:

X-Accel-Expires: 500  
Cache-Control: max-age=100

–  
Igor S.

> **[Igor Sysoev](http://sysoev.ru/en/)**

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 10, 2010, 9:03pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/3 "2010-05-10T21:03:11Z")

</div>

## Vinay Y S Wrote:

> Hi,  
> Is there developer documentation on how http  
> caching works in nginx? I’m  
> seeing weird caching behavior where it’s caching  
> responses with Cache-Control: private headers.

nginx completely ignores the `private` keyword and  
will cache your document regardless.

> As I’ve asked in another thread, I’m also trying  
> to understand how I can  
> enable/disable caching per request based on a  
> cookie or a header set by  
> upstream server.

You can send `Cache-control: max-age=0` or  
`Cache-control: no-cache` to disable nginx proxy cache.

Note that because `private` is ignored, you cannot tell  
nginx to not use the proxy cache while still allowing  
the browser to cache (for example,  
`Cache-control: max-age=3600, private`). You can only  
disable the proxy cache in the configuration file based  
on the current Location. I don’t really understand this  
behavior; I think private should be honored.

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,42865,85008#msg-85008](http://forum.nginx.org/read.php?2,42865,85008#msg-85008)

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 10, 2010, 9:44pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/4 "2010-05-10T21:44:44Z")

</div>

Igor S. Wrote:

> However, you may say nginx “X-Accel-Expires: 0” to  
> not cache such  
> responses. You may say different cache times for  
> nginx and  
> browsers/transit proxies:

Oh, thank you. That is very useful.  
Jim

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,42865,85035#msg-85035](http://forum.nginx.org/read.php?2,42865,85035#msg-85035)

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 10, 2010, 11:55pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/5 "2010-05-10T23:55:53Z")

</div>

On Mon, May 10, 2010 at 2:15 PM, Igor S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > nginx completely ignores the `private` keyword and
> 
> responses. You may say different cache times for nginx and  
> browsers/transit proxies:
> 
> X-Accel-Expires: 500  
> Cache-Control: max-age=100

Ach… is this really true? It is a fundamental HTTP spec violation to  
ignore “private” cache-control directives in a proxy (even a reverse  
proxy I would think).

It says in the documentation that it will obey cache-control headers  
here:

> **[GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki...](https://github.com/nginxinc/nginx-wiki)**
>
> ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com

Is the documentation incorrect? Are “private”, “no-transform”,  
,“proxy-revalidate”, and other such headers are ignored by nginx? I  
just introduced caching into our QA environment for a whole site,  
expecting sane behavior on the part of nginx. I guess I better do some  
multi-user testing or roll it back out of caution…

–  
RPM

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 10, 2010, 11:41pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/6 "2010-05-10T23:41:15Z")

</div>

Igor S. Wrote:

> However, you may say nginx “X-Accel-Expires: 0” to  
> not cache such  
> responses. You may say different cache times for  
> nginx and  
> browsers/transit proxies:

Oh, thank you. It didn’t occur to me to use X-Accel-Expires.

Jim

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,42865,85039#msg-85039](http://forum.nginx.org/read.php?2,42865,85039#msg-85039)

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 11, 2010, 3:06am UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/7 "2010-05-11T03:06:08Z")

</div>

Hello!

On Mon, May 10, 2010 at 04:55:03PM -0500, Ryan M. wrote:

> > > `Cache-control: no-cache` to disable nginx proxy cache.  
> > > However, you may say nginx “X-Accel-Expires: 0” to not cache such  
> > > responses. You may say different cache times for nginx and  
> > > browsers/transit proxies:
> > 
> > X-Accel-Expires: 500  
> > Cache-Control: max-age=100
> 
> Ach… is this really true? It is a fundamental HTTP spec violation to  
> ignore “private” cache-control directives in a proxy (even a reverse  
> proxy I would think).

There are lots of situations where you have to cache private data  
on reverse proxy. And you can do this safely by providing  
appropriate proxy\_cache\_key.

I agree that private data shouldn’t be cached by default, but I  
don’t see any “fundamental violation” here. In HTTP terms nginx  
is origin server, and it’s up to it’s admin to configure it to do  
whatever he want.

> It says in the documentation that it will obey cache-control headers here:  
> [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/NginxHttpProxyModule#proxy_cache)

Wiki isn’t documentation, it’s user-contributed content.

> Is the documentation incorrect? Are “private”, “no-transform”,  
> ,“proxy-revalidate”, and other such headers are ignored by nginx? I  
> just introduced caching into our QA environment for a whole site,  
> expecting sane behavior on the part of nginx. I guess I better do some  
> multi-user testing or roll it back out of caution…

The only cache-control directives currently honored are “no-cache”  
and “max-age=”.

And yes, using proxy\_cache on some arbitrary backend which wasn’t  
designed to work with nginx isn’t really good idea (at least right  
now).

Maxim D.

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 14, 2010, 3:11pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/8 "2010-05-14T15:11:38Z")

</div>

2010/5/10 Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> There are lots of situations where you have to cache private data  
> on reverse proxy. Â And you can do this safely by providing  
> appropriate proxy\_cache\_key.

Only if you’re able to create separate nginx locations or different  
proxy\_cache\_key definitions for public items versus potentially  
private dynamic pages based on URI alone. This isn’t possible with  
quite a few content management and collaboration systems, especially  
those which dynamically return images or other content from a  
database. In such systems, the URLs are usually something like  
[http://myserver.com/content/id354325435ed434](http://myserver.com/content/id354325435ed434), with Cache-Control and  
Content-Type headers being set dynamically. You can’t add a cookie or  
anything else to the proxy\_cache\_key without giving up caching of  
public items.

> I agree that private data shouldn’t be cached by default, but I  
> don’t see any “fundamental violation” here. Â In HTTP terms nginx  
> is origin server, and it’s up to it’s admin to configure it to do  
> whatever he want.

Nginx with the HTTP proxy module certainly doesn’t meet the definition  
of “origin” in RFC 2616. I agree the flexibility to go against the  
specification is desirable, but as you say, the default behavior  
should conform to the RFC.

> Wiki isn’t documentation, it’s user-contributed content.

Is the Russian version at [nginx: документация](http://sysoev.ru/nginx/docs/) the only  
official documentation? I wish I understood Russian and was able to  
help keep an up-to-date English version. Google translate does a  
decent job, but with technical content that’s not always good enough.

It would probably be best to distribute revision-controlled HTML  
documentation which correspond to source code releases. I am willing  
to help the project in this area.

> The only cache-control directives currently honored are “no-cache”  
> and “max-age=”.

## I started looking at the source, but was thoroughly confused because there are so few comments. It seems that a simple patch to ngx\_http\_upstream.c which sets “u-\>cacheable = 0;” if a “private” keyword (or for that matter other Cache-Control headers than nginx does not yet understand) wold be a workable first step…

RPM

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [May 14, 2010, 4:30pm UTC](https://www.ruby-forum.com/t/nginx-http-proxy-caching/181848/9 "2010-05-14T16:30:40Z")

</div>

2010/5/10 Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Wiki isn’t documentation, it’s user-contributed content.

## I updated the English Wiki at [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/NginxHttpProxyModule#proxy_cache) to provide a better description of the current behavior.

RPM
