Archive for the 'WordPress' Category

WordPress internal object cache killed this site’s performance

As you may have noticed, this blog became very sluggish recently. Fortunately, I’ve narrowed down the cause of the lag to the WordPress internal object cache, which is supposed to increase site performance, but in my case it slowed down page load times by more than 10x, sometimes much more.

My blog’s symptoms:

  • Disabling all plugins and reverting to the default theme and displaying only 1 blog post on the homepage did not really affect my page loadtime.
  • The load delay was not an issue with PHP/MySQL at all. My page was completely executed and outputted by PHP in about 0.5-1 second (according to various plugins that showed the script execution time), but it took 10x that to cache the entire page to disk or load 100% of the page in a browser.
  • The page load lag has nothing to do with the browser on the client side. I tried Firefox, IE, Safari, and even external tools like Pingdom Full Page Tester.
  • The browser loaded 95% of the page and for some reason stalled for a long time on the footer section; making the footer empty didn’t help, and profiling the footer itself showed that PHP executed it in 0.06 seconds.

On a whim, I removed the following line that I inserted in wp-config.php to get back to a vanilla WP setup.

define(ENABLE_CACHE, true);

This line enables WP’s built-in object cache and is supposed to improve performance slightly. Problem solved!

This object cache supposedly caches database queries to disk to reduce CPU and database overhead. This should increase performance in most cases unless your disk I/O performance is very poor, like Dreamhost’s NFS storage system. This feature seems to be undocumented and had security issues in the past, but is commonly recommended as a safe way of increasing performance. I have heard that the object cache hardly improves performance, but I’d never imagined that it would slow my site down by 10x or more.

Disabling the object cache brought my page load times back to normal, with all my plugins enabled. I suppose the feature is disabled by default for a reason. If your blog is suffering from performance issues and your plugins or themes are not the cause, try disabling the object cache (if you enabled it). Comment out

define(ENABLE_CACHE, true);

in wp-config.php if needed.

However, some of the performance improvements in the upcoming WordPress 2.4 apparently have to do with the object cache. /me confused. :( I will try to find out more about what exactly the object cache does and what it did to kill my site’s performance. Thanks again, Jeff from NFSN, for helping me troubleshoot my site’s performance issues.

If you liked this post, please subscribe to my feed. Thanks for visiting!

Bad Behavior and Squid’s default caching behavior don’t play nice

I wrote earlier about Bad Behavior sporadically blocking me from my own site. It turns out the problem was Squid’s default behavior of caching error messages for 5 minutes (my host deploys Squid in front of its server clusters for load balancing and other purposes). Thus, if a spambot or other undesirable gets blocked by Bad Behavior, and I or anyone happens to visit the site within 5 minutes, Squid will serve up the 403 access forbidden message.

Bad Behavior’s devevloper Michael Hampton and Jeff from my host NearlyFreeSpeech were both extremely patient and helpful in helping me solve this problem. They both independently provided me with this very simple solution: add

header("Vary: *");

after line25 in banned.inc.php in the Bad Behavior plugin.

The “Vary: *” header tells the cache (like Squid) that the content of this particular page changes based on unknown factors. Since the criteria for whether the cache should serve the same version of this page to future requests is unknown, the cache shouldn’t cache the page. Contrast the “Vary: *” header with the “Vary: accept-encoding” header where the cache will serve up the same version of the page to requesters with the same “accept-encoding” value, and get a fresh copy if the value is different.

I am told that, in the ideal world, Bad Behavior should not have to send such a header with its error messages because the official HTTP standards (RFC 2616) state that content should not be cached unless the Cache-Control headers explicitly allow it. However, Squid is “non-compliant” in this particular case as it caches error messages for 5 minutes unless the default negative_ttl setting is changed. Luckily, it’s not a painful choice to choose between being compliant with HTTP standards and being complaint with default Squid settings (which I assume are widely used). Sending an extra “Vary: *” header doesn’t seem to have any downsides.

Thanks again, Michael and Jeff, for helping me debug this problem and humoring my newbish questions.

Bad Behavior false positives: blocked from my own site

Update: My mistake. Michael Hampton is still supporting Bad Behavior. Maybe I’ll figure out what’s wrong after all.

I’ve disabled the Bad Behavior plugin because it was sporadically blocking me from my own site. Bad Behavior in theory blocks spambots and other desirables from viewing your website altogether, saving your bandwidth and resources and acting as a first-line defense, complementing anti-spam solutions like Akismet and the new Defensio.

I really love the concept, but since Bad Behavior blocks access entirely, false positives are very costly. Unwittingly blocking genuine visitors to my site would be very very bad. I’ve tried to find the problem following instructions from the FAQ and this blog post on false positives, to no avail.

Unfortunately, the plugin doesn’t seem to be in active development, and the email for reporting false positives appears to be dead. Oh well, I guess Akismet alone will have to do.

WP Super Cache should be safe to use

WP Super Cache should be safe to use and has been re-enabled. There was a bug that might have allowed the creation of directories outside the supercache directory but nothing more. That bug has been fixed. See Donncha’s official statement and Chris’s account of the bug and debugging process in more detail. Thanks, Donncha, for the speedy resolution of this issue!

I’m now testing the development version of WP Super Cache to help iron out the bugs. Pardon the dust. :)

CSS and JavaScript consolidation: fetching one big file is faster than ten small files

So you’ve enabled caching, gzipped your files, but your site still loads slowly? The culprit might be the large number of separate CSS and JavaScript files that the browser must load when first visiting your site.
Continue reading ‘CSS and JavaScript consolidation: fetching one big file is faster than ten small files’

WP Super Cache disabled due to potential XSS vulnerabilities

I just came across disturbing “reports” of WP Super Cache being vulnerable to cross-site scripting code injection attacks. Just to be safe, I’ve disabled WP Super Cache and reverted to WP Cache v2.1.2 until the issue is resolved. Donncha is very responsive so I’m sure this scare will be behind us very soon.

Sources:
Donncha’s Thursday Links
wp-super-cache cached too far for me (and others)
wp-super-cache vulnerable to PHP Injection?

Minify and compress Javascript/CSS with minimal CPU overhead

With modern web designs, especially those with AJAXy features, you’d be shocked to find that Javascript and CSS contribute significantly to the amount of data your browser downloads for a webpage. Usually, the Javascript and CSS files are larger than the HTML webpage itself. Continuing my trend of debunking popular or common beliefs, read on for why on-the-fly JS/CSS compression that you read about on Digg often will actually crash your site hard when you get Dugg. I also present a simple yet more efficient way of compressing your files.
Continue reading ‘Minify and compress Javascript/CSS with minimal CPU overhead’