WordPress Super Cache

I’ve been using the WP-Cache 2 plugin for some time, as it offers pretty effective file-based caching of WordPress pages to help reduce the load on the database server and reduce page generation time. But the plugin has kind of languished without any real updates for months(?) or years(?).

Donncha O Caoimh, the WordPress guru who’s name I’ll never be able to pronounce, released an updated and refined caching plugin called WP-Super-Cache, based on the great start offered by WP-Cache 2.

Traditionally, if someone wanted to run a high-performance weblog, or an enterprise-level weblogging system, they really had only 2 choices.

  1. MovableType – because it generates static HTML for every page of the site, and only runs code when posting new content (posts or comments). It can, in theory, scale pretty much infinitely, but can also take for fracking EVER to publish content because it may have to regenerate static files for EVERY page on the site (if you change the theme, you get to create 5,000 new .html files to reflect it).
  2. WordPress on some bad-ass hardware. WordPress.com runs on it, but they use 23 bajillion servers, with jaw dropping MySQL clustering and replication. Dynamic content with query caching, etc… Works great, but needs a fair bit of care on the back end to manage the tiers of MySQL (or Oracle?) database servers, and multiple webservers.

Now, there’s a pretty kickass third option.

  1. WordPress on commodity hardware, with WP-Super-Cache

WP-Super-Cache does some great caching, storing the output of dynamically generated pages, and returning those rather than hitting the database. It doesn’t even have to fire up PHP to spit out the cached pages – it’s essentially running as a static file server. Kinda like MovableType. But with lazily bound cache that gets regenerated as needed. You don’t have to staticize an entire website, just the pages that are being requested. And they’re updated every hour or so, so the load on the server should be extremely low.

If your server is kosher, it’ll also gzip the cached pages, saving disk space, time and bandwidth (sadly, neither of my servers seem to play nicely with the gzip “super cache” option – I’ll play more later).

Now, my blog likely still won’t survive a full-on Slashdotting because I’m running on an inexpensive shared hosting provider (Dreamhost). But it should survive a pretty respectable amount of traffic (i.e., way more than I currently get) so I should be good to go. And ucalgaryblogs.ca should be able to serve out some pretty decent traffic loads, assuming I manage to actually market it and get folks to use it…

WP-Super-Cache also works out of the box on WordPress MultiUser. It installs as a mu-plugin with minimal effort, once you RTFM. The options, oddly, don’t show up in “Site Admin” but in the “Options” panel on the main blog of a WPMU installation.

WordPress Performance Tuning

My blog often has fits of sucktacular performance. After digging around, and bugging DreamHost support for some ideas, I’ve made some progress.

I had been running wp-cache to enable file-based caching, thinking that would help optimize performance of the site (fewer database calls should equal better performance) – except that DreamHost apparently uses NFS-mounted storage for accounts. As a result, filesystem access is a bit laggy, so the file-based caching was actually (apparently) slowing the site down (as suggested by 4+1 ways to speed up wordpress). Disabled wp-cache and set define('WP_CACHE', false); in wp-config.php

I also noticed that there were 2 requests for linked files that were returning 404 errors, which in turn trigger my fancy schmancy 404 page and so add significant lag to the page load. Turns out the OpenID Delegation plugin had bad references to openid.js and openid.css so I fixed that, and page loads are at least cosmetically snappier now.

One other modification I made was to (temporarily?) disable the “Similar Posts” plugin and sidebar display. I really like the functionality that provides, but it was adding too much processing time to generating individual post pages. It works by using the MySQL full text index on the blog posts table, which gets a bit slow with lots of posts and MyISAM tables (table-level locking and lots of extra queries means slower site responses). I’ll look into optimizing that a bit and re-enabling in the future.

Also, I had the Mandigo theme set to automatically rotate through a set of banner images, meaning WordPress was having to crunch through the blogbanner/wide directory itself in order to pick up a banner image. Instead, I just set up my .htaccess file to intercept the URL for the default Mandigo banner image, and Redirect it to rotator.php so it should be a bit better now.

It’s still not running as fast as I’d like, but it’s just a blog. I could always trim out more plugins and pick a simpler theme, but I’m pretty happy with the functionality I have at the moment. At least it’s performing better than Twitter…

Update: I turned off the General Stats widget (but left the plugin active) – there’s no need to count every word of every comment and post when displaying every page on the blog. That info is available on the Archives page, where it belongs. That removed several very heavy queries from the typical page generation load.  I also updated Mandigo, which mentioned some optimizations in the changelog. The blog feels snappy enough now for me to stop worrying for awhile…