search by tags

for the user

adventures into the land of the command line

nginx fastcgi cache

There’s some awesome write-ups on the internet about this stuff.

Nginx can cache the results of FastCGI, uWSGI proxied requests and even the results of load balanced requests (requests sent “upstream”). This means we can cache the results of requests to our dynamic applications.

If we use Nginx to cache the results of a FastCGI process, we can think of the FastCGI process as the Origin Server and Nginx as the Cache Server.

Here’s an example vhost config utilising fastcgi proxy cache:

fastcgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

server {

    # Boilerplate omitted

    set $no_cache 0;
    log_format caching '$remote_addr $host $remote_user [$time_local]  '
                   '"$request" $status $body_bytes_sent $upstream_cache_status '
                   '"$http_referer" "$http_user_agent" $request_time $upstream_response_time $pipe';
    access_log  /var/log/nginx/cache.log caching;

    # Example: Don't cache admin area
    if ($request_uri ~* "/(admin/)")
    {
        set $no_cache 1;
    }

    location ~ ^/(index)\.php(/|$) {
            fastcgi_cache cache;
            fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
            fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
            add_header X-Fastcgi-Cache $upstream_cache_status;
            fastcgi_cache_bypass $no_cache;  # Don't pull from cache based on $no_cache
            fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache

            # Regular PHP-FPM stuff:
            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php-fpm.sock;
            fastcgi_index index.php;
    }
}

You can tell if it’s working if there’s stuff inside /var/lib/nginx/cache. You’ll also see response headers for items matched in your location block:

$ curl -X GET -I mygroovysite.com/index.php
X-Fastcgi-Cache: MISS

$ curl -X GET -I mygroovysite.com/index.php
X-Fastcgi-Cache: HIT

$ curl -X GET -I mygroovysite.com/admin
X-Fastcgi-Cache: BYPASS

If you’re doing some load testing, to determine the efficiency of your shiny new cache, you can get a summary with:

awk '{print $11}' /var/log/nginx/cache.log  | sort | uniq -c

2327 HIT
 536 MISS

I like this last command best ;)