WordPress Optimization Bible

Update: Automate and simplify many things outlined in this article for free using ManageWP.

This WordPress optimization tutorial is the most comprehensive guide to WordPress optimization created with the intention of helping you troubleshoot performance related issues and provide you with guidelines on how to speed up your WordPress site..

If you ever experienced slow WordPress admin panel, "MySQL server has gone away" message, pages taking forever to load or you want to prepare your site for a major increase in traffic (for example Digg front page) this is the guide for you.

1. Check the Site stats

Most commonly the problem with slow loading sites is just the sheer size of the page. A typical webpage today will be loaded with images, flash, videos and javascripts all which take a significant portion of bandwidth.

If you want to start dealing with this issue seriously you need to get Firefox browser, Firebug extension and Yslow plugin.

Yslow module will allow you to get a performance score from 0-100.  Getting your site to 80+ score should be your aim.

Try to keep your page size under 100KB. Try to keep it under 50kb if possible. If you have a lot of multimedia content then by all means learn to use YSlow.

Learn about ways to improve the page loading speed.

Another useful Firefox extension worth checking out is Google's Page Speed.

2. Check your (Vista) System

In rare occasions when you are loading your and other sites slowly, it can be your Vista system that is causing the slowdown.

If you are running Vista check this article for a diagnosis and a possible solution.

3. Check the Plugins

Plugins are usually the prime suspect for slowdowns. With so many WordPress plugins around, chance is you might have installed a plugin which does not use the resources in an optimum way.

For example such plugins that caused slowdowns in the past have been Popularity contest, aLinks or @Feed.

To check plugins, deactivate all of them and check the critical areas of the site again. If everything runs OK, re-enable the plugins one by one until you find the problematic plugin.

After finding the cause you can either write a message to the plugin author and hope they fix it or search for an alternative.

4. Check your Theme

If it's not the plugins, and you are troubleshooting slowdown of the site, you should check it with a different theme.

Themes can include code with plugin capabilities inside the theme's function.php file so everything what applies to plugins can apply to the theme.

Also, themes may use excessive JavaScript or image files, causing slow loading of the page because of huge amount of data to transfer and/or number of http requests used.

WordPress comes installed with a default theme and it's best used to test the site if your theme is the suspect for poor performance.

If you discover your theme is causing the slowdowns, you can use the excellent Firebug tool for Firefox browser to debug the problem. Learn more about Firebug, your new best friend.

You can also use this site get general information about the site very fast.

5. Optimize Database Tables

Database tables should be periodically optimized (and repaired if necessary) for optimum performance.

I recommend using WP-DBManager plugin which provides this functionality as well as database backup, all crucial for any blog installation.

WP-DBManager allows you to schedule and forget, and it will take care of all the work automatically.

Other alternative is manually optimizing and repairing your table through a tool like phpmyadmin.

6. Turn off Post Revisions

With WordPress 2.6, post version tracking mechanism was introduced. For example, every time you "Save" a post, a revision is written to the database. If you do not need this feature you can easily turn it off by adding one line to your wp-config.php file, found in the installation directory of your WordPress site:

define('WP_POST_REVISIONS', false);

If you have run a blog with revisions turned on for a while, chance is you will have a lot of revision posts in your database. if you wish to remove them for good, simply run this query (for example using the mentioned WP-DBManager) plugin.

DELETE FROM wp_posts WHERE post_type = "revision";

This will remove all "revision" posts from your database, making it smaller in the process.

NOTE: Do this with care. If you are not sure what you are doing, make sure to at least create a backup of the database first or even better, ask a professional to help you.

7. Implement Caching

Caching is a method of retrieving data from a ready storage (cache) instead of using resources to generate it every time the same information is needed. Using cache is much faster way to retrieve information and is generally recommended practice for most modern applications.

The easiest way to implement caching (and usually the only way if your blog is on shared hosting) is to use a caching plugin.

The most commonly used is WP Super Cache.

A new kid on the block, W3 Total Cache is more powerful alternative, maturing with every day.

8. MySQL Optimization

MySQL can save the results of a query in it's own cache. To enable it edit the MySQL configuration file (usually /etc/my.cnf) and add these lines:

query_cache_type = 1
query_cache_limit = 1M
query_cache_size = 16M

This will create a 16 MB query cache after you restart the MySQL server (the amount depends on the amount of available RAM, I use around 250MB on 4GB machine).

To check if it is properly running, run this query:

SHOW STATUS LIKE 'Qcache%';

Example result:

Qcache_free_blocks 718
Qcache_free_memory 13004008
Qcache_hits 780759
Qcache_inserts 56292
Qcache_lowmem_prunes 0
Qcache_not_cached 3711
Qcache_queries_in_cache 1715
Qcache_total_blocks 4344

Further MySQL Optimization:

There a lot of options you can play with so here is my MySQL config file instead, tuned in for 4GB, quad-core dedicated machine. This will most probably not work for your machine out of box, use it just as a general guideline.

[mysqld]
bulk_insert_buffer_size = 8M
connect_timeout=10
interactive_timeout=50
join_buffer=1M
key_buffer=250M
max_allowed_packet=16M
max_connect_errors=10
max_connections=100
max_heap_table_size = 32M
myisam_sort_buffer_size=96M
query_cache_limit = 4M
query_cache_size = 250M
query_cache_type = 1
query_prealloc_size = 65K
query_alloc_block_size = 128K
read_buffer_size=1M
read_rnd_buffer_size=768K
record_buffer=1M
safe-show-database
skip-innodb
skip-locking
skip-networking
sort_buffer=1M
table_cache=4096
thread_cache_size=1024
thread_concurrency=8
tmp_table_size = 32M
wait_timeout=500

# for slow queries, comment when not used
#log-slow-queries=/var/log/mysql-slow.log
#long_query_time=1
#log-queries-not-using-indexes

[mysqld_safe]
nice = -5
open_files_limit = 8192

[mysqldump]
quick
max_allowed_packet = 16M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

Tip #2:
Here is a further read regarding MySQL optimization and another one here.

Extremely useful mysqlrepot tool will help you tweak that mysql like nothing. Mysql tuner is one of the best and quickest tools out there to tell you how can you fix up your database. MySQL Tuning primer and MySQL Activity Report are another two scripts to try out.

Maatkit is an extremely useful toolkit for managing MySQL.

MySQL slow query log is valuable for getting info about most problematic queries. To activate it you can edit your my.cnf

log-slow-queries=/var/log/mysql-slow.log
long_query_time=1
log-queries-not-using-indexes

This will create a log of slow queries and those not using indexes. Now you need to be able to identify the slow ones for which you can use external slow log filter and parsing tools. Using 'EXPLAIN' is an effective way to understand and optimize complex queries.

You can also install mytop, a 'top' command clone that works with MySQL.

9. PHP Opcode Cache

PHP is interpreted language, meaning that every time PHP code is started, it is compiled into the so called op-codes, which are then run by the system. This compilation process can be cached by installing an opcode cache such as eAccelerator. There are other caching solutions out there as well.

To install eAccelerator, unpack the archive and go to the eAccelerator folder. Then type:

phpize
./configure
make
make install

This will install eAccelerrator.

Next create temp folder for storage:

mkdir /var/cache/eaccelerator

chmod 0777 /var/cache/eaccelerator

Finally to enable it, add these lines to the end of your php.ini file (usually /etc/php.ini or /usr/lib/php.ini):

extension="eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/var/cache/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

The changes will be noticeable at once, as PHP does not need to be 'restarted'.

Note #1: WP Super Cache and eAccelerator work fine together showing further increase in performance.

Note #2: If you like even more possibility for performance, check the WP Super Cache and eAccelerator plugin.

Note #3: Unfortunately eAccelerator won't work if PHP is run as CGI. You can try using fastcgi which will work with suExec and eAccelerator.

Note #4:W3 Total Cache mentioned earlier already utilities both memcached and APC making it amazingly fast.

10. Web Server optimization

Apache optimization is something books have been written on so I will first forward you to this article here. Indepth apache compilation tips here, performance tuning here, VPS tips here and keep alive tips here.

You can easily test changes in your configuration by running a test from your command prompt

ab -t30 -c5 http://www.mysite.com/

and comparing results. I get around 200 req/s on VPS server.

For more flexible testing you can use Autobench which works in conjunction with httperf, another benchmarking tool.

Use a fast web server like nginx to serve static content (ie. images) while passing dynamic requests is another popular technique you can use to improve performance.

Note #1: More cool resources. Optimizing Page load time and a great series on website performance.

Note #2: You can find even more tips&tricks on Elliot Back's site

11. "MySQL server has gone away" workaround

This WordPress database error appears on certain configurations and it manifests in very slow and no response, usually on your admin pages.

Workaround for this MySQL problem has been best addressed in this article.

This problem evidently exists, but the suggested fix is valid only until you upgrade your WordPress. Hopefully it will be further researched and added into the WordPress core in the future.

Note #1: Sometimes increasing MySQL wait_timeout to 1000 will help with this issue.

12. Fixing posting not possible problem

If you experience WordPress admin panel crawling to a halt, with inability to post or update certain posts, you are probably hitting the mod_security wall.

ModSecurity is Apache module for increasing web site security by preventing system intrusions. However, sometimes it may decide that your perfectly normal WordPress MySQL query is trying to do something suspicious and black list it, which manifests in very slow or no response of the site.

To test if this is the case, check your Apache error log, for example:

tail -f /usr/local/apache/logs/error_log

and look for something like this:

ModSecurity: Access denied with code 500 (phase 2) ... [id "300013"] [rev "1"] [msg "Generic SQL injection protection"] [severity "CRITICAL"] [hostname  www.prelovac.com"] [uri "/vladimir/wp-admin/page.php"

It tells you the access for this page was denied because of a security rule with id 300013. Fixing this includes white-listing this rule for the page in question.

To do that, edit apache config file (for example /usr/local/apache/conf/modsec2/exclude.conf) and add these lines:

SecRuleRemoveById 300013

This will white list the page for the given security rule and your site will continue to work normally.

13. RSS Pings and Pingbacks

Reasons for slow WordPress posting may include rss ping and pingback timeouts.

By default WordPress will try to ping servers listed in your ping list (found in Settings->Writing panel) and one of them may timeout slowing the entire process.

Second reason are post pingbacks, mechanism in which WordPress notifies the sites you linked to in your article. You can disable pingbacks in Settings->Discussion by un-checking option "Attempt to notify any blogs linked to from the article (slows down posting)".

Try clearing ping list and disabling pingbacks to see if that helps speed up your posting time.

Following are the general Rules for optimizing page loading time

14. Use subdomains to share the load

Most browsers are set to load 2-4 files from a domain in parallel. If you move some files to a different domain (subdomain will work) the browser will start downloading 2-4 more files in parallel.

It is good idea to move your theme image files to a subdomain you create. I have created demo.prelovac.com/images and moved my theme images there. I have then changed the theme style.css to reflect the full url to the new image files. Job done!

15. Minimize the number of HTTP requests

You can lower the number of HTTP requests by using fewer images (or placing all images in one large image and position them with CSS), fewer javascripts, fewer css files (usually meaning fewer plugins).

Good effort has been made by PHP speedy plugin which will merge all your JavaScript and all CSS files in one big file which really helps in lowering the HTTP request numbers. The biggest drawback of PHP Speedy is that it's not 100% compatible with all plugins.

Also use the CSS Sprite generator to move all your images into one image and then use CSS background-position to display them. This will cut your number of HTTP requests significantly.

16. Compress the content using apache .htaccess

If you have our own server you can chose to gzip all content sent to browsers. This will lower the loading time significantly as most html pages compress very well.

Add this code to your .htaccess

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/x-javascript application/x-httpd-php application/rss+xml application/atom_xml text/javascript

17. Create expires headers

Expire headers tell the browser how long it should keep the content in cache. Most of the images on your site never change and it is good idea to keep them cached locally.

Add this to your .htaccess (make sure mod_expires is loaded in your apache if you have problems)


ExpiresActive on
ExpiresDefault "access plus 30 days"
Header unset ETag
FileETag None

Here is an alternative setting:

Header unset Pragma
FileETag None
Header unset ETag

# 1 YEAR

Header set Cache-Control "public"
Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT"
Header unset Last-Modified

# 2 HOURS

Header set Cache-Control "max-age=7200, must-revalidate"

# CACHED FOREVER
# MOD_REWRITE TO RENAME EVERY CHANGE

Header set Cache-Control "public"
Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT"
Header unset Last-Modified

Use cacheability engine to check your cache configuration.

18. Cache Gravatars

Many blogs use Gravatars, the little images next to your comments. However gravatars have two big flaws in regards to site optimization:

  • Every gravatar image is a new HTTP requests even if same image is loaded (page with 100 comments would have 100 additional HTTP requests)
  • Gravatar images do not contain expire headers

What we can do is create a local gravatar cache, where images would be cached and served from our site. Ideally you would place the gravatar cache on a separate subdomain (see first heading).

I use a plugin from Zenpax.com which allows all gravatars to be cached locally.

19. Optimize the images with smush.it

It is often overlooked that your images can be optimized (made smaller) which can significantly reduce loading times.

Wouldn't it be perfect if you could open a site, press a button in your browser and get all images on the site optimized and made available in a single zip file. That is possible thanks to smush.it and their Firefox plugin. It is amazing how effective this is!

20. CSS on top, JavaScript on bottom

It is golden practice to put CSS files on top of the page so they are loaded first. JavaScript files should be placed on the bottom of the page (when possible). I have created a simple plugin which will move the properly registered JavaScript files to the bottom of your pages. The plugin is called Footer javaScript.

Conclusion

Modern webservers and websites have grown to depend on many different factors.

This article covered various approaches to optimization from system level apache, PHP and MySQL changes to settings within your WordPress.

I hope following this guide will help you create a fast and responsive WordPress based site.

196 Comments

  1. May 20th, 2011

    thank u very much, i will try these.

  2. May 19th, 2011

    Wow, superb post! Thanks a lot for it!

  3. Apr 16th, 2011

    this is really good to know some awesome tips.
    thank you for sharing.

  4. Mar 28th, 2011

    Sorry, I think we send the same comment 2 times, Greetings

  5. Mar 28th, 2011

    Very good information, thanks for sharing, Greetings

  6. Mar 28th, 2011

    Hi Vladimir, Thanks for such a great article. Very well written and easy to understand, even for us novice SEO and optimization types.

  7. Mar 26th, 2011

    Hi,

    i used for my Blog http://www.tarifemonster.de the stop of post revision. I think this was a good option to optimize the blog. Also i let load the most Plugins in the footer so the Site can build much faster.

  8. Mar 16th, 2011

    Great-great-great article. may i go here other time to chek other best article.
    thanks a lot.

  9. Mar 8th, 2011

    thank u very much, i will try these.

  10. Feb 26th, 2011

    This is what I really want. I was looking for this certain info for a long time. Thank you and good luck.

  11. Feb 26th, 2011

    just write a post on my french blog to optimize your WordPress blog

  12. Jan 12th, 2011

    Vlad:
    I am using your Blue Grace theme and am so impressed with the cleanliness of your code I had to comment. Very organized and clean.

    Trying to learn more about the multi-pages widget in Blue Grace theme led me to your site and this optimization guide. Very nice.

    Thanks...

  13. Jan 1st, 2011

    Thanks I new to used wordpress for blogging, I need this information but not yet undurstand all what you write here.

  14. Dec 24th, 2010

    Dear All,

    I am finding it difficult to optimize the website on wordpress. most of the plugins need customization, as i am weak in programming.

    If you know some plugins we give automation while making the websites for SEO please let me know i will be thank full to you.

    Most of the plugins requires setting i have tried alot but still not able to find a good plugin for my website.

    Please do help me.

  15. Dec 3rd, 2010

    love this programming, thank you for port

  16. Oct 11th, 2010

    There are quite a few of your recommendations listed here that are handled by the W3 Total Cache plugin like combining and enhancing the CSS and Javascript files. They have really made some serious advances with this plugin, not to mention the use if a CDN which can really speed up your site.

    Mike

  17. Oct 9th, 2010

    Really great list and tips Vladimir! Appreciate the data.

    Do you still find you need to add the .htaccess expire header data even tho you have the w3 total cache plugin?

  18. Oct 8th, 2010

    Really complete, no need to look further. Thanks :)

  19. Oct 5th, 2010

    Brilliant advice here Vlad. Thank you for compiling this list. Off to tweak my sites.

  20. Sep 29th, 2010

    Excellent news and very informative. I have not been blogging long but I am learning a lot from many blogger's especially you. Your information is very rich and worth every penny :) Thank you very much for sharing so much to everyone here in cyber space. Great work Vladimir

    • Sep 29th, 2010

      You are of course aware that no pennies are spent in the process? ;)

      • Nov 16th, 2010

        Hi Vladimir
        I am very glad that I found your site as the information and tips about optimizing wp blogs that you provide here is excellent.
        Thanks
        Mike

  21. Sep 23rd, 2010

    Good information, I will try in my web site.

  22. Cody
    Sep 15th, 2010

    Good overview.

    Just a couple remarks though ...

    I think it was idea #12.

    Maybe explain what -f to tail does ?

    I know but not all admins may know - even if they should:

    Follow mode so the use would be run the command in the terminal, and then go to browser - try to do what was failing and then go check where you ran the command. Hit ctrl-c (in most cases - it is configurable of course) to stop following the file. Basically, as the log file changes, tail follows it by printing it to the screen.

    There's of course other options but follow is indeed a good way given it's in real time.

    Regarding #16 :

    Apache themselves suggest - if you can (which I hope you could if you have your own server) - to add rules as such in the httpd.conf file. Minor ? I don't know as personally I have all my rules in there as a matter of then I can disable .htaccess files as well as control it all. Personal preference of course, but they (apache) suggest even more performance gain.

    Fwiw.

    Nice blog btw.

    Kind regards,
    Cody

    • Sep 23rd, 2013

      A Comment very long :D
      I like it
      Tinh le

  23. Sep 6th, 2010
  24. Sep 3rd, 2010

    It is wonderful. Thank for your post

  25. Sep 2nd, 2010

    I got more good nuggets out of this post than I can express. LOL... I'm not even advanced enough right now to apply all of these techniques, so I'm implementing what I can and I'll come back later to get more. Thanks Vladimir.

Have your say

Your email is never published nor shared. Required fields are marked *

*
*

  • ManageWP