Batcache for WordPress

[I meant to publicize this after a period of quiet testing and feedback but the watchdogs at WLTC upended the kitten bag and forced my hand. Batcache comes with all the usual disclaimers. If you try it on a production server expect the moon to fall on your head.]

People say WordPress can’t perform under pressure. The way most people set it up, that’s true. For those who host their blog for $7.99 a month (do they also run Vista on an 8086?) the best bet is to serve static pages rather than dynamic pages. Donncha’s WP-Super-Cache does that brilliantly. I’ve seen it raise a server’s capacity for blog traffic by one hundred times or more. It’s a cheapskate’s dream.

WP-Super-Cache is good for anyone with a single web server with a writable wp-content/cache directory. To them, the majority, I say use WP-Super-Cache. What about enterprises with multiple servers that don’t share disk space? If you can’t or won’t use file-based caching, I have something for you. It’s based on what uses. It’s Batcache.

Batcache will protect you

Batcache implements a very simplistic caching model that shields your database and web servers from traffic spikes: after a document has been requested X times in Y seconds, the document is cached for Z seconds and all new users are served the cached copy.

New users are defined as anybody who hasn’t interacted with your domain—once they’ve left a comment or logged in, their cookies will ensure they get fresh pages. People arriving from Digg won’t notice that the comments are a minute or two behind but they’ll appreciate your site being up.

You don’t need PHP skills to install Batcache but you do have to get Memcached working first. That can be easy or hard. We use Memcached because it’s awesome. Once you know how to install it you can create the same kind of distributed, persistent cache that underpin web giants like and Facebook.

What Batcache does

The first thing Batcache does is decide whether the visitor is eligible to receive cached documents. If their cookies don’t show evidence of previous interaction on that domain they are eligible. Next it decides whether the request is eligible for caching. For example, Batcache won’t interfere when a comment is being posted.

If the visitor and the request are eligible, Batcache enters its traffic metering routine. By default it looks for URLs that receive more than two hits from unrecognized users in two minutes. When a URL’s traffic crosses that threshold, Batcache caches the document for five minutes. You can configure these numbers any way you like, or turn off traffic metering and send documents right to the cache.

Once a document has been cached, it is served to eligible visitors until it expires. This is one place where Batcache is different. Most other caches delete cached documents as soon as the underlying data changes. Batcache doesn’t care if it’s serving old data because “old” is relative (and configurable).

What Batcache doesn’t do

It doesn’t guarantee a current document. I repeat this because reliable cache invalidation is a typical feature that was purposefully omitted from Batcache. There is a routine in the included plugin that tries to trigger regeneration of updated and commented posts but in some situations a document will still live in the cache until it expires. This routine will be improved over time but it is only an afterthought.

Batcache doesn’t automatically know the difference between document variants. Variants exist when two requests for the same URL can yield two different documents. Common examples are user agent-dependent variants formatted for mobile devices and referrer-dependent variants with Google search terms highlighted. In these cases you MUST take extra steps to inform Batcache about variants to avoid serving a variant to the wrong audience. The source code includes examples of how to turn off caching of uncommon variants (search term highlighting) or cache common variants separately (mobile versions).

Where Batcache is going

I want to make Batcache easier to configure by adding a configuration page and storing the main settings in memcached as well as the database. This way you won’t have to deploy a code change to update the configuration. However, conditional configurations (e.g. “never cache URLs matching some pattern”) and variant detection will probably always live in PHP.

I want to have Batcache serve correct headers more reliably. On some servers it can detect the headers that were sent with a newly generated page and serve them again from the cache. But when that doesn’t work you will have to take extra steps to serve certain headers. For example you must specify the Content-Encoding header in the Batcache configuration or add it to php.ini. I want this sort of thing to be done automatically for all server setups.

I know that Batcache is not ideal for most WordPress installations. It saves us a lot of headaches and expense at, so maybe it can help other large installations. If you try it, I want to hear from you whether it worked and how well. I am also keen to see what new configurations and modifications you use.

As always, this software is provided without claims or warrantees. It’s so experimental that it doesn’t even have a version number! Until the project grows to need its own blog, keep an eye on the Trac browser for updates.

32 thoughts on “Batcache for WordPress”

  1. now that sounds amazing, still, do you also plan on maling this plugin wpmu compatible? a lot of people would be much obliged…

  2. I hope that early release did not cause too many headaches. The instructions for installation suggest loading a page twice to receive the debug info in the header but that only works if you have not commented and if you are not logged in. Caught my by surprise at first.

    Also, could something like this also be used for spam floods? I have some ideas (and enough spam floods) to test it out if you are interested.

    Thanks for a great implementation, I am testing it on wltc.

  3. I’m currently using WP-Super-Cache just ’cause it’s easy (112000 pageviews today and no noticeable change in load) and the site I use it on doesn’t use comments, but damn, this sounds very interesting. I’ll definitely be keeping an eye on it!

  4. Er, not that it really matters, but WP-Super-Cache actually handed 207000 pages today (I guess stats are less accurate than Apache logs).

    But anyway, I forgot to ask — I understand Batcache is mainly designed for those on multi-server environments where file based caching can’t be done, but what about single beefy server environments?

    I’m currently using a lightly modified WP-Super-Cache + Squid. Would I see an improvement or no with Batcache + Squid? Note I don’t have any dynamic content except new posts.

  5. @Viper007Bond If you basically do not have comments super-cache should be very effective, and not be i/o intensive, so should be enough. Seen that you already have in place also a reverse proxy (squid) – you would expekt to see just one of the two systems in place – i see no use for a different memory-based caching method, but of course ymmv

  6. We are currently using Super Cache at the official MoBlog Site. Is the Batcache suitable for WordPress Mu or we should wait for the beta version…

    Just wondering 🙂


  7. Can this be installed on top of other caching systems?

    If I’m using WP-Cache (or some variant of), PHP Speedy, etc… ?

    In other words, does this “play nice” with other server speed tweaks? I’m on a self-hosted dedicated server…

    Much thanks!

  8. Jack: Batcache should be just fine for MU. However if you are already using WP-Super-Cache you don’t need Batcache. I would still recommend installing the Memcached backend.

  9. Paul: WordPress can only use one “advanced cache” at a time. So no, it can’t be used with WP-Cache. (Remember that Batcache is meant for sites with more than one web server.) I have not heard from anyone using PHP Speedy.

  10. Hey Andy ! We’ve deployed batcache/memcache in a multi-server setup, and it’s been a godsend, but still having a few issues here and there. was wondering if you could offer some assistance?
    – User-Agent detection: Had a function to handle this to serve up mobile site, but regular users were getting mobile version for some reason
    – Content type Headers: images / pdf files are coming up as garbled text on the screen. I think it’s because it’s being transferred with content-type text/html instead of application/pdf or image/jpg, etc… Tried changing apache_get_headers() to headers_list(), but then the array gets off key, and it starts using the array key (0,1,2,3…) as the header name, and ‘content-type: image/jpg’ as the value, so we get 1: content-type: image/jpg, which clearly doesn’t work =)

    I can shoot you an email if it would be easier to reply to, but hopefully you can at least point me in the right direction on this. WordPress has been a fickly monster to get running smoothly on our setup. We’re getting better with batcache/membache, but still not quite there yet.

    Thanks Andy !

  11. Andy or other Batcache pros in this forum,
    If I turn on “$batcache->unique[‘mobile’] = is_mobile_user_agent();”, I assuming I will still need to create the logic for the is_mobile_user_agent?

    I am running into the mobile caching issue and am hoping that I can get this $unique array to work for the mobile theme.

    Your plug-in is amazing, thanks for putting this together!

    1. Exactly right. You’ll get a fatal error if you don’t define that function. Also note that plugins are not loaded before Batcache, so you’ll have to find an early place to define it.

      1. Andy much appreciated, batcache is working for the mobile version of our site now: !! I included the function for mobile detection right above the “define(‘WP_CACHE’, true);” line in wp-config -> worked like a charm.

    2. Hey Chris ! We’ve got this successfully working on our site. If you need any help with this, we can send you the function that we’re using to check for mobile user agents.

  12. Hi Andy, great work on this plugin. I’ve modified this plugin by adding a few lines from minify project hosted on to minify HTML source. I am checking to see if you think this would be great for other users too and want to update plugin on repository. Let me know.

  13. I just got this working! Yay! Just in case any other dopes are reading this….. I thought it wasn’t working and spent a couple of hours trying to figure out if I had screwed something up in installing Memcached before I realized the problem was that I needed to clear my cookies in order to get a batcache generated page. Duh! So happy now! Thanks Andy 🙂

  14. I’ve not seen updates to the plugin in 3 years.. does it still work well, or has it been replaced by another plugin? This post is 4 years old and am wondering if batcache is still a good alternative to file based caching with Supercache.

    1. @Mikel King Thanks, We ended up going with Varnish with hyperdb. The invalidation of the cache was important for us and was hoping that batcache might add this in later versions. I keep a watch out for new versions.

Comments are closed.