High performance WordPress

Of all the WordPress installations I manage, two of them bring in a rather large number of hits.

To speed up WordPress I usually just enable the MySQL query cache and install the eaccelerator PHP opcode cacher. On one particular box, an Intel 1.3Ghgz PIII this increased performance from around 3 requests per second to around 10.

Recently I came across the WP-Cache plugin for WordPress. This takes the finished output from any given wordpress request and caches it to disk, serving directly from the static cache for the next hour (configurable). Any new posts or comments in the mean time immediately mark the cached version stale, so you don’t need to wait around for an hour.

On the same hardware and blog, this increases performance from 10 requests per second to over 250. A 2500% increase in speed.

Lighttpd cache meta language

With WP-Cache, each request still has to incur the penalty of a PHP script execution, even though it’s much shorter one than the usual WordPress path. Lighttpd now has a mod_cml plugin which allows you to script caching decisions in a language called Lua, directly in the web server.

One should be able to implement enough WP-Cache logic with Lua so that Lighttpd can serve the cached static html directly, only executing PHP when the cache is stale.

Looking at the WP-Cache code, all that’s needed is a md5sum hash of the request url and a file modification time check, which seems to be possible in Lua in mod_cml.

The only thing that can’t be done is reading cache files for users with login or comment name cookies, as mod_cml doesn’t seem to provide access to cookies. This would still increase the performance for the majority of requests though.

I’ve not had time to write and test a Lua script yet though.

Apache Bench results

Before WP-Cache

This is ApacheBench, Version 2.0.41-dev
Server Software:        lighttpd/1.4.11
Server Hostname:        geekz.co.uk
Document Path:          /lovesraymond/archive/terrorismistic
Document Length:        16004 bytes
Concurrency Level:      3
Time taken for tests:   4.861144 seconds
Complete requests:      50
Total transferred:      818266 bytes
HTML transferred:       808270 bytes
Requests per second:    10.29 [#/sec] (mean)
Time per request:       291.669 [ms] (mean)
Time per request:       97.223 [ms] (mean, across all)
Transfer rate:          164.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    92  118  91.1     94     649
Waiting:       67   84  54.6     69     393
Total:         92  118  91.1     94     649

Percentage of the requests served within a certain time (ms)
  50%     94
  66%     95
  75%     97
  80%     98
  90%    155
  95%    217
  98%    649
  99%    649
 100%    649 (longest request)

After WP-Cache

I had to run the test for longer else it was too quick for reliable results (and higher concurrency too)

This is ApacheBench, Version 2.0.41-dev
Server Software:        lighttpd/1.4.11
Server Hostname:        geekz.co.uk
Document Path:          /lovesraymond/archive/terrorismistic
Document Length:        16098 bytes
Concurrency Level:      5
Time taken for tests:   3.79451 seconds
Complete requests:      800
Total transferred:      13059990 bytes
HTML transferred:       12942792 bytes
Requests per second:    259.79 [#/sec] (mean)
Time per request:       19.247 [ms] (mean)
Time per request:       3.849 [ms] (mean, across all)
Transfer rate:          4141.32 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    6   5.0      7      22
Processing:     4   11   6.5     11      67
Waiting:        0    7   6.2      7      61
Total:         16   18   4.1     18      80

Percentage of the requests served within a certain time (ms)
  50%     18
  66%     18
  75%     18
  80%     18
  90%     19
  95%     19
  98%     24
  99%     34
 100%     80 (longest request)

WP-Cache and PHP 5.1 bug workaround

Just a quick note, I use PHP 5.1 and came across a bug in WP-Cache that displayed blank pages on first load. It’s an easy one line fix once you know how.

Leave a Reply