Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have added a X-Accel-Expires header on my static contents as well as a Last-Modified header. I would like to know whats the correct setting to cache those elements without caching anything else.

This is what I have at the moment but it doesn't cache anything :

http {
include       /etc/nginx/mime.types;

access_log  /var/log/nginx/access.log;

sendfile        on;
client_max_body_size 2000m; 
keepalive_timeout  65;
tcp_nodelay        on;

gzip  on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

ssl_certificate /etc/nginx/chain.pem; 
ssl_certificate_key /etc/nginx/key.key;

proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:30m max_size=1G;
proxy_temp_path /var/lib/nginx/proxy 1 2;
proxy_cache_use_stale error timeout invalid_header http_502;

server {
    listen       80;
    server_name domain;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_read_timeout 700;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
share|improve this question
up vote 3 down vote accepted

To cache stuff, first you need to create a proxy cache path within the http context, like this:

proxy_cache_path    /var/cache/nginx/site1    levels=1:2    keys_zone=site1:10m max_size=1G;

Then you can also optionally define the proxy cache key. Any request that has the same cache key as a cached entry, will receive the cached reply, if there is one. But default may already be good enough, so, that's entirely optional.

Then to enable the cache in a given context, just mention which cache should be used, like this:

proxy_cache    site1;

According to the description of the proxy cache valid directive, nginx already respects X-Accel-Expires and acts on it, so, you're basically done at this point. Since you don't want to cache anything that doesn't include X-Accel-Expires, then you probably want to add a value of 0 as the default valid time (setting X-Accel-Expires within your content should overwrite this default value).

proxy_cache_valid    0m;

I shall presume that other than for the lack of any caching, your config file is otherwise valid, and your proxying itself already works.

Then, basically, all you need to do to fix your config is add the following to your http, server or location context:

proxy_cache    cache;
proxy_cache_valid    0m;

(Also, you might want to ensure that the cache path exists and has correct permissions, of course.)

Regarding the mentioned habrahabr article/example, I don't think it's actually correct to be including $http_if_modified_since in the cache key, because you can potentially end up with a lot of multi-cached entries, effectively wasting your cache.

Also note that nginx likely doesn't proxy X-Accel-Expires header -- it only uses it internally, and IIRC may not serve this header forward. To alter such behaviour, you have to explicitly ask for it to be proxied, too (in case you want to debug your content through nginx, and see how your app sets the header etc):

proxy_pass_header "X-Accel-Expires";
share|improve this answer
+1. If you use multiple levels of nginx, remember to set proxy_pass_header "X-Accel-Expires"; at each level. – Justin Jan 29 at 4:39

There is a good howto about using of X-Accel-Expires header in nginx on Russian IT blog. I think, it may be very useful in your case.

share|improve this answer
thank you, I use nginx as a proxy, I'm not using fastcgi. Do you think I can still use those settings ? – mnml Dec 28 '12 at 13:29
Sure, why not? This is very well described in official nginx documentation. Of course, depending on your project, you may have to experiment with some of the settings. – hangover Dec 29 '12 at 5:27
hangover, please consider expanding your answer beyond just 'here's a link'. If that ever link goes away your answer becomes totally useless. – Mxx Jan 3 '13 at 18:02

I think the reason is that cache is defined but not enabled -- proxy_cache cache; is missing.

share|improve this answer
that will cache everything right ? I only want to cache when the X-Accel-Expires is specified – mnml Jan 2 '13 at 16:35

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.