Mar 112012

This is an article of mine, originally published on Wazi

WordPress , the popular content management system (CMS), is easy to configure and use, and is well supported by its community of professional consultants. WordPress depends for its operation from a full stack that includes an operating system, database, web server and PHP. If you can optimize this stack, you can improve the performance of your site. Here are some tips and best practices for a configuration that can improve performance without forcing a hardware upgrade.

In the first part of this guide we have seen what to check and modify in the operating system and database server (mysql)
In the second part I have presented the instructions to set the http server (Nginx to be exact) and PHP .

Today we will see APC, the configuration of WordPress and Varnish.

Alternate PHP Cache

I strongly suggest installing the Alternate PHP Cache (APC), an opcode cache that’s easy to install and configure. Opcode caches save the compiled form of PHP scripts in shared memory to avoid the overhead of parsing and compiling the code every time the script runs. This saves RAM and reduces script execution time.

To install APC run yum install php53u-pecl-apc. You can find the program’s configuration file at /etc/php.d/apc.ini. Among the parameters in it is apc.shm_size, which specifies how much memory to use for APC. Below is a sample configuration that I use on a 512MB Linux system:
apc.optimization = 0
apc.use_request_time = 1

For a full explanation of these settings, refer to the online documentation.

APC includes a web page where you can see the usage of the cache, including fragmentation and other useful information. Copy /usr/share/doc/php53u-pecl-apc-3.1.9/apc.php to your document root and point your browser to it.

One word of warning: If you don’t periodically restart PHP-FPM, your cache could become fragmented, as you’ll be able to see by visiting that web page. To avoid this, periodically empty the cache. I use a cron setting that once a day calls a web page on my site, which I call apc-clear.php, that empties the cache. It also checks that the address invoking it is local so it cannot be called from outside. Here is the content of apc-clear.php:

if (in_array(@$_SERVER['REMOTE_ADDR'], array('', '::1')))
  echo json_encode(array('success' => true));

And this is my cron:

0 6 * * * /usr/bin/curl --silent


Now that you have the infrastructure set up, you can install WordPress easily by following the five-minute install guide on Also install the nginx compatibility plugin; it will make your life easier if you use short-links and permalinks.

After the initial install is a good time to run a first performance benchmark. Pingdom and WebPagetest can give you the total time to load your WordPress site and some additional evaluation.

One plugin in particular can improve the user experience of your site. W3 Total Cache (W3TC) caches every aspect of your site, reducing download times and providing transparent content delivery network (CDN) integration. Once installed via the admin section of your WordPress site, it adds a Performance section at the bottom of the left-hand menu in your control panel. W3TC has too many options to explain them all here, but let’s look at the main features and how you can tweak settings to suit your site.

On the main W3TC page set

Page Cache: Enable
Page Cache Method: Disk Basic

For typical environments, disk basic is best, or disk enhanced if you are in a shared environment. You can always test the various methods to see which one fit well for your site; the best setting also depends on what kind of stress you’re trying to optimize your server for. Generally speaking, with opcode caching, pages are stored in RAM, so they’re served faster, but php-interpreter is involved in serving requests, which can put a load on the CPU. By contrast, with disk-based caching, there’s no load on php-interpreter if a page is already cached, but disk cache is slower than RAM.

The defaults are fine for most other options, but change the following:

Minify: Enable
Minify Mode: Manual
Minify Cache Method: Opcode Alternative PHP Cache (APC)

Database Cache: Enable
Database Cache Method: Opcode Alternative PHP Cache (APC)

You might need to modify these settings, depending on how you use your site. For instance, on my site I use a plugin that for every article read does an update to count the visit. If I enable the database cache, this plugin stop working. In a shared environment, database caching can slow down everything, so test it by enabling and disabling it before you go live.

Object caching increases performance for highly dynamic sites – ones that use the Object Cache API:

Object Cache: Enable
Object Cache Method: Opcode Alternative PHP Cache (APC)

Enable HTTP compression and add headers to reduce server load and decrease file load time:

Browser Cache: Enable

If you have a CDN you can set it up in the specified fields, after which theme files, media library attachments, CSS, and JavaScript files will load instantly for site visitors:

CDN: Enable
CDN Type: Select your CDN

Page Cache Settings
So much for the first page of settings. Now go into Page Cache Settings and look at Cache Preload. With this option, you can automatically fill the cache by using an XML sitemap. To do this, set these options:

Automatically prime the page cache: Enabled
Update interval: 3600
Pages per interval: 100
Sitemap URL:

Minify Settings

Minify is an application that speeds your site by removing comments and line breaks from CSS, HTML, and JavaScript files, combining similar files together, and zipping them. With Minify, the size of the files is reduced to make loading the site faster, but configuring Minify is the hardest part of W3TC configuration; you have to specify the list of all your JavaScript and/or CSS files, and some of them will not work once Minified, so it’s a trial and error procedure. If you’re uncomfortable with looking at HTML source code and finding CSS and JavaScript files there, skip this section. You don’t have to Minify; Page Cache will work just fine. But you can use Minify to squeeze out every bit of performance optimization and site speed. To use it:

Enable JS minify settings, and in the section “JS file management” put all your JavaScript scripts. Enable CSS minify settings and in “CSS file management” put all your CSS files.

The defaults of the other W3TC tabs should be fine. You can now save all the settings. After saving, W3TC will tell you if something is wrong or not configured.

Now you have configured every aspect of W3TC. To activate it you have to load some nginx rules.
In the tab named Install you have all the rules that you need to load into your Nginx configuration to enable all your choices. The easiest thing to do is to copy the rewrite rules on this page and paste them in a file. W3TC will suggest a location; one good position is /etc/nginx/conf.d/w3tc.conf. Go back to your nginx configuration file and add this line just before the last }:

include /etc/nginx/conf.d/w3tc.conf;

Restart nginx with the command service nginx restart.

Now benchmark your site again. The changes you made should be enough to give you a satisfying result – but if you want more, and you’re not scared by more configuration, there’s Varnish Cache, an open source, state-of-the-art web application accelerator.


Before you install Varnish, be aware that if you have a lot of dynamic pages that use cookies and forms, Varnish will be useless, or could even cause problem if you configure it badly. If your site is not so dynamic and you can remove most of your cookies, you’ll get wonderful results.

To use Varnish, you must configure nginx to listen to port 8080 so that Varnish can listen to port 80 and forward any requests that aren’t in its cache to the backend server. To do this, just change the listen directive of your virtual host in /etc/httpd/conf.d/yoursite.conf from 80 to 8080, then restart nginx.

Varnish is available in the EPEL repository. Install it with the command yum install varnish.

The program’s main configuration file is /etc/varnish/default.vcl. To make Varnish cache a WordPress website appropriately, clear all cookies exchanged between the server and the client except for the one set for WordPress admin. If you don’t do this, login to the admin account will fail because the pages will be cached. This is an example of a VCL file for a WordPress site:

 backend default {
     .host = "localhost";
     .port = "80";

acl purge {

sub vcl_recv {
        if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
        # Remove cookies and query string for real static files
        if (req.url ~ "^/[^?]+\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.*|)$") {
                unset req.http.cookie;
                set req.url = regsub(req.url, "\?.*$", "");

        # Unset all cookies if not WordPress admin - otherwise login will fail
        if (!(req.url ~ "wp-(login|admin)")) {
                unset req.http.cookie;

sub vcl_hit {
        if (req.request == "PURGE") {
                set obj.ttl = 0s;
                error 200 "Purged.";

sub vcl_fetch {
        # Drop any cookies WordPress tries to send back to the client.
        if (!(req.url ~ "wp-(login|admin)")) {
                unset beresp.http.set-cookie;

Varnish and W3TC

W3TC supports Varnish, it can purge the cache every time you post a new article to do this, in the main page you just have to enable the option “Enable varnish cache purging” and put as address for the Varnish server.

Explaining all the Varnish Control Language directives goes beyond what I can cover in this article, but in the Varnish documentation you can find a full explanation of the commands and many examples.

After you’ve gotten Varnish working, repeat the benchmarks. You should see another improvement.

WordPress setup and optimization is a complex topic. I hope this article gives you some material to work with. While I’ve presented some common setups that could be perfect for you, they may need to be changed, depending on your server hardware, software, or kind of service. Test the various options and repeat the benchmarks until you find the perfect setup for your site.

Popular Posts:

Flattr this!

  6 Responses to “Supercharge WordPress, Part 3”

  1. Awesome guide! It’s been a big help with setting up APC on my server.

    One question: where did you add the cron? I tried adding it in root with crontab -e, but it won’t run. If I add it in Cronjob Manager within cPanel it gives me the “Top secret”-message. I edited the script now, so it doesn’t check where the request comes from and it works. But I’d like to make it safe anyway… Any suggestions?

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>