Caching a Django app with Nginx + FastCGI

I just spent a stupid amount of time trying to figure why [Nginx][nginx] was failing to cache my [Django][django] app responses. The Django app is running as a FastCGI backend and I have Nginx using the [`fastcgi_cache` directive][cache] to cache responses.

The answer is that [Nginx since version 0.8.44 does not cache backend responses if they have a “Set-Cookie” header][0844]. This makes perfect sense because you don’t want a response which sets a cookie to be cached for subsequent requests, but I was stupid because I had totally forgotten that my Django app was using a POST form for all responses for non-authenticated clients (due to how [Django’s CSRF middleware][csrf] does its stuff).

The solution was to change the app so that it uses the GET method on the form in question, which in this case is fine from a security point-of-view.

The moral of this story is I should pay attention to my HTTP response headers and that I am badly short-sighted both figuratively and literally. With that fixed the site has gone from 15 requests per second to ~2000 requests per second!

[nginx]: http://nginx.org/
[django]: http://www.djangoproject.com/
[0844]: http://nginx.org/en/CHANGES
[csrf]: http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
[cache]: http://wiki.nginx.org/HttpFcgiModule#fastcgi_cache

One thought on “Caching a Django app with Nginx + FastCGI

  1. Mike

    Thanks, you helped me figure out why nginx wasn’t caching my django pages even if your description was a bit hard to understand. I got it working with these additional options:

    proxy_cache_key “$scheme.$proxy_host.$request_uri.$cookie_sessionid”;
    proxy_ignore_headers Set-Cookie;

    Do you see any potential problems?

Leave a Reply

Your email address will not be published. Required fields are marked *