WordPress Performance

This answer is customized for cohousing.org. (change domain name)

If you’re serving a busy site using WordPress, you should pay attention to how quickly your copy of WordPress runs. By spending a little time “tweaking” WordPress, you can dramatically affect how fast it runs (and therefore how many visitors it can handle).

This page describes techniques for speeding up WordPress, including FastCGI and WP Super Cache. To show you what a difference these can make, here are some rough performance testing results on our servers for an “out of the box” WordPress installation:

  • Standard WordPress installation: 2 page views per second
  • WordPress with FastCGI enabled: 8 page views per second
  • WordPress with WP Super Cache enabled: 500 or more page views per second for cached files

In other words, using these techniques allows your site to handle well over 200 times as many visitors per second.

To get the full benefit, you do need both FastCGI and WP Super Cache. That’s because WP Super Cache only speeds up “cached” pages, and pages won’t always be cached. If they aren’t cached, they load at the slower speed of either 2 or 8 per second, and you definitely want that to be as fast as possible.

On this page:

Enable FastCGI

Using FastCGI for PHP scripts allows the script to stay preloaded in memory, waiting for a page request. This eliminates the normal PHP startup time (which can be as much as half a second per request).

We have detailed technical instructions about enabling FastCGI for your account on our FastCGI page, but note that you don’t need to do it yourself: just contact us and we’ll be glad to do it for you at no charge.

Install WP Super Cache

WP Super Cache sends the same page to multiple visitors (if it hasn’t changed) without running the same WordPress script code every time. This vastly speeds up loading times for pages that are viewed by multiple people.

Installing this free plugin is the biggest performance improvement you can make.

We have simple instructions explaining how to install the plugin on our WP Super Cache page (and again, we’ll be glad to install it for you if you prefer).

If you’ve already installed WP Super Cache but the load is still high, be sure you’re using the recommended settings we show on that our page.

Think twice about mobile site plugins like “WPtouch”

Plugins like WPtouch show visitors a different version of your site on mobile phones. However, this feature comes at a heavy cost: the caching effect of WP Super Cache (and similar caching systems) is bypassed for each mobile viewer.

This can be a problem. Even if only 5% of your visitors use mobile devices, your total site CPU usage will more than double with WPtouch if the non-cached page is twenty times slower to load (which is common). We’ve seen perfectly working sites brought to their knees by simply installing WPtouch.

If you have a small number of visitors, plugins like WPtouch are fine. If you have many visitors, though, you’ll have to seriously consider whether it’s worth it.

(As an aside, the “proper” way to show different sites to mobile browsers is for themes to use CSS3 media queries, like the Yoko theme. This approach works perfectly with caching plugins in the sense that it doesn’t increase server load at all. Unfortunately, not many themes support media queries yet.)

Avoid other slow plugins, especially “WP Spam Free”

The idea of WP Super Cache is that for most requests, there is no PHP code that needs to be executed on the server.

However, a small number of WordPress plugins add JavaScript that loads an extra non-cached PHP script for each page view. This defeats the purpose of WP Super Cache.

We strongly recommend avoiding plugins that operate this way. Some that we know of are:

In addition, avoid plugins that perform extremely inefficient database queries, including:

Finally, you should not use any plugin that contains this line of PHP code:

$wp_rewrite->flush_rules

This causes (potentially large) MySQL database updates for every page viewed, slowing down WordPress dramatically. One such plugin is Sitemap Generator For WordPress MU.

Avoid unnecessary plugins

Every plugin you enable makes WordPress a little slower. Some resource-intensive plugins make WordPress much slower.

We almost never hear complaints about the speed of WordPress sites that don’t use many plugins. Speed only becomes a problem when sites use lots of plugins. We’ve seen several sites that run more than ten times slower than a standard WordPress installation because of the plugins they use.

If you care about the speed of your site, don’t use plugins you don’t need, and test every plugin individually to see how much it slows down your site.

Use real files for “favicon.ico”, “robots.txt”, etc.

If a visitor requests a file that doesn’t exist, WordPress displays a useful “file not found” page that includes similar pages, links, and so on. However, that page takes time to generate.

In some cases, it’s normal for a file to not exist. In particular, many browsers and search engines request files named “favicon.ico” and “robots.txt”, and some Apple devices like the iPhone request files named “apple-touch-icon.png” and “apple-touch-icon-precomposed.png”.

When those files don’t exist, your site still works properly, so the missing files don’t cause visible problems. However, these requests use valuable WordPress processing power to construct the custom “file not found” page, and that effort is completely wasted: no human ever sees the page WordPress creates.

The best and simplest solution is to make sure these files aren’t missing. Create a “favicon.ico” file and add “robots.txt”, “apple-touch-icon.png” and “apple-touch-icon-precomposed.png” files. The robots.txt file can be completely empty if you want.

Alternately, you may want to add this line to your .htaccess file, just before the existing WordPress “RewriteCond %{REQUEST_FILENAME} !-f” line:

RewriteCond %{REQUEST_URI} !^/(apple-touch-icon.png|apple-touch-icon-precomposed.png|crossdomain.xml|favicon.ico|robots.txt)$

That line prevents the custom WordPress 404 PHP code from running when several common “non-human” requests are made for missing files.

Don’t run WordPress for missing images

As discussed in the above section, WordPress will run and generate a custom “file not found” page when a request comes in for a missing file.

You can configure your Web site to immediately return a standard 404 error code when a missing image file is requested (rather than having WordPress run).

To do so on a site that is not using the WordPress “network of sites/WordPress MU” feature, add these three lines to your .htaccess file, before the existing “# BEGIN WordPress” section:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(jpg|jpeg|png|gif|ico|swf|bmp)$ - [nocase,redirect=404,last]

Don’t put those lines above the whole WordPress section if your site uses the WordPress “network of sites/WordPress MU” feature, though. That feature relies on other parts of the .htaccess rules “fixing” the path to missing images, so the exact location of the lines matters.

For a site that uses the WordPress “network of sites” feature, you can instead add these two lines just before the existing “RewriteRule . index.php [L]” line:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(jpg|jpeg|png|gif|ico|swf|bmp)$ - [nocase,redirect=404,last]

The two lines must be in exactly the right place, so be careful to only put them immediately before the “RewriteRule . index.php [L]” line if you’re using a “network of sites”.

Make sure you don’t have any “404 Not Found” URLs

Every “404 Not Found” URL uses significant resources to show a custom WordPress 404 page to the visitor. Check your error logs to be sure your site isn’t generating 404 errors.

Prevent search engines from indexing threaded comments

If your site gets a large number of comments, you may find that search engines try to index many URLs that include “?replytocom=” at the end, like this:

http://www.cohousing.org/something/something/?replytocom=12345

These URLs are part of the WordPress threaded comment feature. Unfortunately, the question mark “query string” in the URL makes it impossible for caching plugins like WP Super Cache to deliver a cached version, so the full WordPress PHP script gets run each time. That’s fine if a visitor is really replying to a certain comment, but it’s not fine for search engines to reindex every single URL on your site through hundreds of different “?replytocom=something” URLs.

If you have this problem on your site, adding these four lines to the top of your .htaccess file will fix it:

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "msnbot|Googlebot|bingbot|Slurp|ScoutJet|MJ12bot|Baiduspider|Ezooms|YandexBot|Exabot"
RewriteCond %{QUERY_STRING} ^replytocom=\d+$
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI}? [redirect=301,last]

These lines detect certain search engines that try to index these, and simply redirect them back to the original page URL, without running any PHP code.

Use appropriate caching and compression

If your site uses many external image files, JavaScript files or CSS stylesheet files, set up appropriate caching and compression rules for those files.

Should I do anything else?

The tips above are almost certainly all you need to know.

People often ask us if they should also “minify” files, combine CSS and JavaScript, and lots of other things they’ve seen mentioned on other sites. If you’re comfortable doing those things and you want an extra small amount of performance, feel free to try them — but in our experience, they make little difference except with the very highest volume sites, and probably aren’t worth your trouble.

See where it’s still slow

After doing everything above, use a tool like WebPageTest, Google Page Speed or Yahoo! YSlow to see what part of your site is slow.

If you find that most of the time is spent on connections to external sites other than your own cohousing.org, try to eliminate as many of those connections as possible.

Can all this really help that much in the “real world”?

Yes. We have several customers using FastCGI and WP Super Cache who have easily “survived” having their WordPress site listed on the Digg home page, with sustained page view rates of 20-30 pages per second for several hours, even on our most basic Web hosting plan.

Advanced users can use the shell command line to test their own results with the ApacheBench program. Here’s a real result from our own blog with WP Super Cache installed:

$ /usr/sbin/ab -n 40 -c 4 http://blog.tigertech.net/

Concurrency Level:      4
Time taken for tests:   0.31100 seconds
Complete requests:      40
Failed requests:        0
Write errors:           0
Total transferred:      1849520 bytes
HTML transferred:       1836800 bytes
Requests per second:    1286.17 [#/sec] (mean)
Time per request:       3.110 [ ms ] (mean)
Time per request:       0.777 [ ms ] (mean, across all concurrent requests)

In this case, our servers delivered over 1200 page views per second. Real world results won’t be that fast because of networking overhead, but it does show that the WordPress software is not a bottleneck at all in this situation.