We are implementing fast CGI cache (not not the proxy version) but it seems that our upstream cache hit is always MISS. If we hijack public/index.php by not running require_once($craftPath."/vendor/autoload.php"); and simply echo time the cache gets created and hit. We noticed that Craft adds cache control, pragma and expires headers by default. We tell FastCGI to ignore the headers with no luck.

Does Craft do anything to not allow FastCGI caching?


location ~ \.php$ {
    fastcgi_ignore_headers X-Accel-Expires Expires Cache-Control;
    fastcgi_cache cacher;
    fastcgi_cache_valid 200 60m;
    fastcgi_cache_methods GET HEAD;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
  • Did you ever figure the out? You also need to hide Craft's default cookie otherwise nginx won't hit the cache. Something like fastcgi_hide_header Set-Cookie will work. Oct 9, 2015 at 18:09
  • @RitterKnight I've been exploring using fastcgi_hide_header Set-Cookie which does exactly what I need. The problem is, I can't seem to figure out how to do it conditionally. For example, we don't want to strip the Set-Cookie headers if we aren't serving it up from the cache (otherwise things like the AdminCP can't set their session cookies). Any thoughts? Jan 5, 2017 at 0:23
  • One thing that works out of the box is to duplicate Craft's index.php file and name it whatever you want, like indexadmin.php. Make a location block that corresponds to the cp trigger and point requests at that file for backend and front end requests at the regular craft index.php. A slightly cleaner way that works within an if block or location block is the 3rd party more_clear_headers module. If you use ubuntu/debian it's bundled with some PPAs of nginx (the nginx-extras package iirc). Jan 5, 2017 at 14:22
  • I just learned that Craft 3 is going to be configurable so it won't set a session unless it needs one. This is going to be a big boon in this respect. Jan 14, 2017 at 19:20

1 Answer 1


Found this while searching for a solution. I fixed it by moving this line to the top of the vhost file:

    fastcgi_ignore_headers X-Accel-Expires Expires Cache-Control;

After this all my requests are properly cached and my site loads really fast! My entire vhost file:

fastcgi_cache_path /etc/nginx-cache levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers X-Accel-Expires Expires Cache-Control;

server {
        listen   80;
        charset utf8;
        root /home/user/htdocs/public;
        index index.php;
        server_name domain.com;

        set $no_cache 0;

        # Don't cache the CMS admin area
        location /admin {
                set $no_cache 1;

        gzip            on;
        gzip_min_length 10;
        gzip_proxied    expired no-cache no-store private auth;
        gzip_types      text/plain application/xml application/x-javascript text/css image/svg+xml;
        gzip_vary on;

        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_pass unix:/var/run/domain-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

                fastcgi_cache phpcache; # The name of the cache key-zone to use
                fastcgi_cache_valid 200 30m; # What to cache: 'code 200' responses, for half an hour
                fastcgi_cache_methods GET HEAD; # What to cache: only GET and HEAD requests (ot POST)
                add_header X-Fastcgi-Cache $upstream_cache_status; # Allow us to see if the cache was HIT, MISS, or BYPASSED inside a browser's Inspector panel
                fastcgi_cache_bypass $no_cache; # Dont pull from the cache if true
                fastcgi_no_cache $no_cache; # Dont save to the cache if true

         location ~ ^(.*)$ {
                 try_files $uri $uri/ /index.php?p=$uri&$args;

        location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff|ttf|svg)(\?ver=[0-9.]+)?$ { expires 1w; }

        location ~ /\.ht {
                deny all;
                return 404;
  • The problem you might run into here is that the on-disk cache is going to contain all of your Set-Cookie headers, so it'll be serving up the same CraftSessionId to everyone, for instance. Jan 5, 2017 at 0:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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