Take the 2-minute tour ×

The following headers (from a static media response) don't lead to caching in Firefox. In Chrome they do.

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 22 Dec 2012 21:20:39 GMT
Last-Modified: Fri, 21 Dec 2012 19:28:54 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: public, max-age=86400
Content-Encoding: gzip

My Nginx server for static content looks like this:

server {
    listen 80;
    server_name static.example.com;

    # Logs
    access_log /var/log/nginx/static.example.com.access.log;
    error_log /var/log/nginx/static.example.com.error.log;

    # Root
    location / {
        alias /var/www/app/deps/current/repo/src/example/static/;
        add_header Cache-Control "public, max-age=86400";

I've also tried using expires 24h;, in place of add_header ..., without luck.

I've found numerous, similar complaints on the Internet, but no solutions, nor any ideas of why this is, other than one person's mention of how Firefox purposely strays from the specification for handling HTTP 1.1 Cache-Control headers.

Is there any way to get Firefox to cache my static media, via a header or multiple headers? I don't want 75% of my server's static media requests to come from 20% of my users, just because Firefox is busted.

Note, I'm using Firefox 17.0.1 with default settings, but with Firebug installed and open to the Net tab.


Using, instead:

expires 1d;
add_header Cache-Control public;

Causes the headers to include:

Expires: Wed, 26 Dec 2012 19:54:20 GMT
Cache-Control: max-age=604800, public

This also doesn't cause Firefox to cache the content.

share|improve this question
See comments on cnst's answer below. "Web Developer" was disabling all cache. –  orokusaki Jan 9 '13 at 19:32

2 Answers 2

up vote 1 down vote accepted

How do you determine that Firefox is not caching your files?

When a Last-Modified header is present in a reply, the browser is supposed to be making all subsequent requests for the same URL with a If-Modified-Since header, and then the response from a server may only contain a header (with no body) if the file has not been modified since.

IIRC, Gecko also looks at how old the Last-Modified date is. If it's relatively recent, then it only makes sense that the content changes all the time, and has to be re-requested (with a If-Modified-Since or the like) quite often. On the other hand, if the date is several weeks, months or years old, then the content is likely to be cached for an extended period of time.

Another thing to look at: do you actually have the correct timezone and time on your Firefox machine?

share|improve this answer
Thanks! That's a great help. Do you know if there is a way to prevent Firefox (via my server, assuming FF has default settings) from sending any request after the initial one? Even with just a body returned, this is wasteful, as I have about 12 media items per view and about 20-20 page views per user in my UI. –  orokusaki Jan 5 '13 at 1:31
Not sure you should really worry about this. First of all, I would be surprised if Gecko would be sending these subsequent requests (with If-Modified-Since) all the time, it's probably only done with the recently-modified files and only every couple of requests or so; second, if it's just static files, these requests are probably really cheap to complete due to nginx efficiency and inode cache. Just for the sake of the experiment, try temporarily changing the modified date of the files with touch(1), and follow the links without doing any manual refresh of any page, and cache will be OK. –  cnst Jan 5 '13 at 2:20
What I meant is, try temporarily changing the modification date to something really old (like 2005), and then try browsing the site without explicitly causing any refresh actions -- just follow the links back and forth, and use the Back and Forward buttons in the browser. I'm pretty sure you'll see that the cache is working just fine in Firefox, and it won't be re-making 20 request for static content for every page. But if you start clicking Refresh here and there, then of course it better make sure that the content on the server has not changed since being cached! –  cnst Jan 5 '13 at 2:33
I just checked and Firefox is indeed requesting without a If-Modified-Since, and is indeed being served the file contents, not just headers. If the file is 200Kb, it'll take about 150ms to download. I'm afraid that Firefox might be a piece of junk. Chrome will cache the content on the first request, even if I don't include any caching headers. Why would Mozilla want their browser to be slow and destroy my users' browsing experience byte by byte? Also, I am just clicking back and forth between links, and back-forward buttons, not refreshing (a refresh will cause even Chrome to re-download). –  orokusaki Jan 5 '13 at 22:46
So... it appears that the "Web Developer" plugin for Firefox actually disables caching altogether, for whatever reason :/ thanks so much for your continued comments, which are what lead me to search for the correct thing and find that. –  orokusaki Jan 9 '13 at 19:31
server {
    expires    1d;
    add_header Cache-Control public;
    listen 80;

Try it this way please like described in nginx docs

So i was courious and tried caching myself With config below. What i have changed is that i started a app on localhost:4567. Whereas in external website a proxypass is configured. More or less like most caching examples i could find.

user nginx; worker_processes 2;
error_log /var/log/nginxtesterror.log; pid /run/nginx.pid;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types; default_type
    log_format main '$remote_addr - $remote_user [$time_local]
                      "$request" ' '$status $body_bytes_sent
                      "$http_referer" ' '"$http_user_agent"
    access_log /var/log/nginx/access.log main;
    sendfile on; #tcp_nopush on; keepalive_timeout 65;
    /var/www/app/deps/current/repo/src/example/static/ levels=1:1:2
    keys_zone=one:200m max_size=1000m loader_files=2000 inactive=60m;
    proxy_temp_path /var/www/app/deps/current/repo/src/example/tmp;
    proxy_cache_valid 1d;
    gzip on; gzip_disable msie6; gzip_static on; gzip_comp_level 4;
    gzip_proxied any; gzip_types text/plain text/css
    application/x-javascript text/xml application/xml
    application/xml+rss text/javascript;
    server { listen 80; server_name static.example.com;
        proxy_set_header Host $host; proxy_set_header X-Real-IP
        $remote_addr; proxy_set_header X-Forwarded-For
        proxy_pass_header Set-Cookie ;
        location ~*
                { expires max; add_header Pragma public; add_header
                Cache-Control public; }

        location / { proxy_pass http://localhost:4567; proxy_cache_key
            $cache_key; proxy_cache one; add_header Cache-Control
            public; proxy_cache_valid 1d; proxy_cache_use_stale error
            timeout invalid_header http_500 http_502 http_504
            http_404; }
    server {
        listen; set $cache_key

        # Logs access_log
        /var/log/nginx/static.example.com.access.log; error_log

        # Root 
        location / {
share|improve this answer
I just tried this. See the update to my question. –  orokusaki Dec 26 '12 at 19:51
Did that work for you? I just tried, without luck :( I'm not looking to cache things in Nginx btw, just serving static content and wanting the browser to cache it. I checked in Chrome, and it's still caching correctly. –  orokusaki Dec 27 '12 at 14:13
My example does server static content as well but on localhost:4567. Proxy is fetching and caching. Did you try to use different Firefox Profiles just to be on the safe side that its not related to browser settigns? –  rhasti Dec 27 '12 at 14:19
Does it cause Firefox to cache content for you though? It doesn't for me. My Firefox settings are factory default. –  orokusaki Dec 27 '12 at 14:35

Your Answer


