Posted by alex on Sep 2nd, 2012

As I was looking for a javascript and css minification plugin solution to reduce the size and number of requests needed to view this page, I stumbled upon W3 Total Cache. Its feature set is impressive, it does static file caching and "minifying", exactly what I wanted.

However, its setup was not as straightforward as Wp Super Cache. See, with this kind of caching tool what you really want is a way to serve static cached files directly from the web server. PHP can serve cached files, but it is much slower (although faster than re-generating the page). On a properly configured server and caching tool, it usually go as this:

IF visitor has a login cookie OR the url contains a query string (?param=value):
the visitor might require specific content, call php to serve a dynamic page
ELSE IF a static version of the requested url exists:
serve it
call php who will generate the missing static page.

Wp Super Cache tries to detect if Apache's mod_rewrite is enabled, but we can force it to use static file caching anyway. This is not possible with W3 Total Cache and it refuses to create static files unless it detects apache, nginx or litespeed. I was a bit annoyed that they decided for me what my server could or couldn't do. But the pros of the tool were enough for me to keep digging.

First I tried to create the test rewrite rules present in nginx or .htaccess example files, maybe W3 would see this as a sign of rewrite support:

url.rewrite-if-not-file = ( 
    "^/wp-content/w3tc/min/w3tc_rewrite_test$" => "wp-content/w3tc/min/index.php?w3tc_rewrite_test=1",
    "^(.*\/)?w3tc_rewrite_test$" => "$1?w3tc_rewrite_test=1",

But "Disk: Enhanced" option was still grayed out. Apparently it doesn't even care about its own test rules, so they can be forgotten. Next simple solution was to trick W3 and make it believe I was running nginx. This is done by adding a single line to your wp-config.php:

$_SERVER['SERVER_SOFTWARE'] = 'nginx 2.2';

And it worked! Usually it is not good practice to manipulate PHP's super globals, but I suggest it anyway because it's easier to maintain. If you were to edit W3, you'd have to remember to edit it every time it is updated.

Now that we fooled W3, we can enable "Disk: Enhanced" option for Page Cache and "Disk" for Minify.

Only thing missing to make it all work are the rewrite rules (Note: they must be inside your virtual host if you have one). One to generate missing minified files and one to serve cached pages.

server.error-handler-404 = "index.php"
#minify doesn't depend on cookies
url.rewrite-if-not-file = ( "^/wp-content/w3tc/min/(.+\.(css|js))$" => "wp-content/w3tc/min/index.php?file=$1")
$HTTP["cookie"] !~ "^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$" {
    url.rewrite-once = ( "^/wp-admin(.*)(?:\?(.*))?$" => "wp-admin$1?$2" )
    url.rewrite-if-not-file += ("^/([^\?]*)$" => "wp-content/w3tc/pgcache/$1/_index.html")

This is not a complete 1:1 translation of W3's nginx rewrite rules, however it was all I needed. If you have problems, take a look at the nginx.conf file generated by W3 Total Cache in your base directory, you might use a feature that I do not.


Hi Alex,

Thanks for this article.

Page cache works fine but Enabling Minify shows the error

"Minify Auto does not work properly. Try using Minify Manual instead or try another Minify cache method. You can also try a lower filename length value manually on settings page by checking "Disable the Minify Auto automatic filename test" "



Go to Top