Here is everything I’ve learnt recently in trying to debug a Wordpress sites performance problems. The site runs on a dedicated server however a lot of these also apply to shared hosting. Remember to please take backups before trying any of these.

Basics

1. Run Wordpress Updates
Often performance issues will be fixed in newer versions of Wordpress, plugins and themes. This may not always be straight forward as it depends on the plugins you have installed and the theme you use.

For all plugins you need to check they are compatible with the latest version of Wordpress, fortunately you can easily see this on Wordpress.org and on the Updates page in newer version of Wordpress.

When I come to run updates I usually take a snapshot of the site to run locally. I can then test and debug any problems before running them on the main site.

2. Empty Caches
Caching can be a great way of speeding up your website however it can also get in the way when trying to debug other problems. When trying something new always clear your caches to make sure cached data doesn’t interfere with anything you’re trying. Most caching plugins have the option to disable caching for authenticated users.

Plugins

3. Disable unused plugins.
If you’re anything like me you will always be trying new plugins for that extra bit of functionality. Check to see if there are any plugins you have that don't add to the value of your site or don't fit in with what your site offers.

4. Enable Caching Plugin
For years I’ve been using WP Super Cache as its easy to setup and works really well. However as I was troubleshooting around this area I found W3 Total Cache, this has more configuration options and the ability to configure a Content Delivery Network (explained below). Most of the default options are a good start however its worth going through every one to see how it affects your site.

5. WP-Optimize
WP-Optimize gives you access to a number of database tasks without needing PHPMYADMIN. Among other features it allows the easy removal of post revisions, comments in the spam queue, and unapproved comments.

Config

All of the following are changes you can make to the wp-config.php file (not to be mixed with wp-config-sample.php).

6. Limit number of revisions
The idea behind this one is that as your site grows by limiting the number of revisions an article can have the wp_posts table grows at a slower rate meaning any SQL queries take less time to complete. The WP-Optimize plugin mentioned above also lets you remove unwanted revisions if you wanted to do this manually.

define('WP_POST_REVISIONS', 3);

To disable post revisions all together add:

define('WP_POST_REVISIONS', false);

7. Increase memory limit
While not strictly for performance if you get out of memory errors you can add the following:
ini_set('memory_limit', '128M');
(This can also be set in php.ini and .htaccess - some shared hosting may not let you overwrite this).

8. Enable Wordpress Caching
There are different levels of caching available - to enable the basic built in caching add:
define('WP_CACHE', true);
(Caching plugins often do this for you.)

9. Add Blog Address and Site Address
Each time a page is loaded it looks up these values from the database - the idea behind hard coding these is that its one less SQL query to do.

define('WP_HOME', 'http://www.imafish.co.uk'); // blog url
define('WP_SITEURL', 'http://www.imafish.co.uk'); // site url

Once these are set in the wp-config.php file they will be greyed out in the Wordpress Admin General settings page.

10. Add Template and Stylesheet Paths
As above this adds in the paths for the template and stylesheet to stop an SQL query to find it.

define('TEMPLATEPATH', '/absolute/path/to/wp-content/themes/<theme>');
define('STYLESHEETPATH', '/absolute/path/to/wp-content/themes/<theme>');

This will disable the ability for you to change themes unless you remove these two lines.

Content Delivery Network (CDN)

11. Use a CDN
A CDN allows you to serve static content such images, scripts and stylesheets locally in a geographical sense to the user. So if the server is US based and the visitor is from the London they would get these files from a server close to London. The idea being that as the data is being served from a fast server/network close to their location loading time will be reduced.

CDNs have been around for a long time however only more recently have they become very easy to integrate with Wordpress. The service I tried was MaxCDN they offer 1TB of bandwidth for $40 making it cheap to play around with. Before you can setup MaxCDN with Wordpress you need to install the W3 Total Cache plugin and you need access to your domains DNS.

11a. Login to MaxCDN go to Manage Zones and click create pull zone. As the name suggests a pull zone will copy content from your site so you don’t have to worry about uploading it to multiple places.

11b. Enter your blogs name for the pull zone, your blogs URL for Origin Server URL, something like cdn.yourblog.com for the Custom CDN Domain, something that describes the zone for Label and tick the compression box.

11c. Maxcdn will give you a URL for your CDN that you need to setup as a cname in your sites DNS. This may take several hours to propagate.

11d. Go to Manage Account > API and add a key. The description can be your blogs name.

11e. Login to Wordpress and go to the W3 Total Cache Performance section. Scroll down to Content Delivery Network, tick enable and select NetDNA/MaxCDN.

11f. Go to the Browser Cache Settings tab and change all three options for ‘Cache Control policy’ to ‘cache (“public”)’

11g. Go to the Content Delivery Network tab in W3 Total Cache and add the API ID and Key provided by MaxCDN. Add the cname you setup under Replace site’s hostname with.

Refresh your cache and visit your site. If everything has worked you should see the urls of your stylesheets, scripts and images have been replaced by the cname URL you setup in MaxCDN.

Server - Apache

The following tips require server level access and are for more advanced troubleshooting and performance tweaking.

12. Enable compression
mod_deflate allows the server to send compressed files to the supporting browser, it will increase CPU slightly however should decrease the amount of time a client is connected to the server, a full tutorial can be found here.

13. Hostname Lookups
Turning off DNS lookups can help make your server capable of handling more traffic.
To do this add to your httpd.conf or Apache2 file (often found in etc/apache/httpd.conf or /etc/apache2/apache2.conf):
HostnameLookups Off

(There are a lot more Apache tweaks however the above two often get good results).

Server - PHP

14. Setup an opcode cache such as APC 
If your sever has APC installed you can take advantage of this with APC Object Cache Backend plugin.

15. Memcache
Memcache is another type of caching for PHP, again there is a plugin - Memcached Object Cache.

16. Batcache
Again Batcache is another caching module - Batcache Wordpress plugin.

(I will confess I didn't try any PHP caching techniques in my recent troubleshooting however where I've used them in the past there have been significant performance gains).

Server - MYSQL 

There are a number of tweaks for mysql.

17. Enable Query Cache
This will cache results to help speed up queries.
In my.cnf find or add:
query-cache-type = 1
query-cache-size = 20M
query-cache-limit = 2M

18. Setup logging of large queries
In my.cnf find or add:
log-slow-queries
long_query_time = 1

Enabling logging of large queries ultimately helped me fix the performance problems with my site. For instance I noticed a query for counting comments to determine popular posts was taking over a second to complete (since the site was now getting a lot of comments). By rewriting this query and setting it to run on a daily cron job I could still generate a list of popular posts without the query running every time the page was loaded.

19. Optimize/Repair Database tables
In PHPMYADMIN or using WP-Optimize you can optimize and repair database tables. Remember to take a backup of these tables first.

Server - General

20. Running Top
While not strictly a performance tip, running top or task manager can help you troubleshoot when the CPU is being used excessively for PHP, Apache or MYSQL.

21. Using ab or siege
Following on from running top tools such as ab or siege can help you test how any of the changes you make affect the performance of the server.

22. Checking with server admin/hosting company
If your server is managed by another company it’s often worth checking with them if there are any performance problems on there. On shared hosting another account maybe be culprit and causing issues so checking with the provider can often fix this.

Theme Optimization

23. Theme Performance
A simple way to see if your current theme is causing problems is to change to another one. If with the new theme the performance is significantly better you can then start disabling plugins and widgets until you diagnose the problem.

Firebug/YSlow

Firebug and YSlow are great browser addons to help diagnose performance issues:

24. Minify/Combine Files
Plugins such W3 Total Cache allow you to minify and combine scripts so that the browser has less and smaller files to download when requesting.

25. Optimize Images
The net tab in Firebug lets you see exactly what is downloaded when loading the page and the total size of all the files. You’ll be able to see any particularly large images and scripts and optimize accordingly. 

I hope you've found this list helpful - if you have any tips please leave them in the comments.

Comments

Great information. It makes a really good blogging service that much better.

Thanks for sharing these tips Pete, I knew some of them, but will try out others since I'm trying to make all my websites load faster.