WordPress Performance

There was a time when we rarely saw problems with WordPress installations causing performance issues.  That was years ago though, and now things sure have changed. Any issues were mostly a mix of forums with weird modifications, extremely high traffic web sites or poorly made custom coded web sites.  It all changed when WordPress became more user-friendly for the average end user and allowed you to install plugins and themes in their WordPress control panel.

WordPress has had plugins and themes from the very beginning however it initially required you to manually upload the files through FTP. This created a barrier where the average end user was not going to take all that extra time to upload the plugins and themes – especially the more complex ones.  This meant only the more tech savvy users were the ones running extra plugins and people were less likely to install unnecessary plugins.

Once users were able to install plugins from the backend of WordPress with a few clicks that was all thrown out – they would see a plugin that sounds cool and install it. Soon it wasn’t uncommon to see WordPress installations with 40+ plugins each adding to the amount of PHP processing and MySQL queries without knowing if the developer cared about performance at all. There are some great plugins though like some of the caching plugins available but unfortunately most users don’t install these even with the easier interface.

The amount of poor performing plugins is really scary for a web host.  You also have plugins that ship with poor default settings and average users don’t bother to change anything. For example several caching plugins don’t cache by default until you enable it / tweak the settings so all they do is add additional overhead. Here are just a few examples of poor performing plugins we encounter:

All In One SEO

It doesn’t take too much searching to see all the users and server administrators crying foul on this plugin.  You have performance benchmarks showing it accounting for close to 75% of page load times which is just outrageous.  What good is SEO improvements on the content of pages when now your pages take magnitudes longer to load?

The same can be said about a lot of the SEO plugins however. I just question their worth if they’re going to ruin performance for actual visitors.  Also with there being penalties for slower page loading this really should matter more.

Yet Another Related Post Plugin

Yet Another Related Post Plugin (YARPP) is a major culprit around these parts for excessive use of system resources.  The creator has said you can disable the features causing the resource issues but as I said earlier rarely do users modify the default settings of their plugins.  So the creator has released a plugin that with the default settings is extremely CPU intensive and with the majority of the WordPress user base being shared hosting users it would probably be wise to run the least impact settings as the defaults and not the highest impact.  Because of this the plugin has a real bad name for itself by end users and server administrators who care about performance.  Here is an example of just how bad this plugin can get:

# Time: 101105 17:27:05
# User@Host: username_wrdp1[username_wrdp1] @ localhost []
# Query_time: 1214.954805 Lock_time: 0.000172 Rows_sent: 0 Rows_examined: 485002033
use username_wrdp1;
SET timestamp=1288992425;
insert into wp_yarpp_related_cache (reference_ID,ID,score) SELECT 2376, ID, (0+ (MATCH (post_content) AGAINST ('textme moretext ')) * 1+ (MATCH (post_title) AGAINST ('features phone iphone 28383 apple ')) * 1+ COUNT( DISTINCT tagtax.term_taxonomy_id ) * 1+ COUNT( DISTINCT cattax.term_taxonomy_id ) * 1) as score
from wp_posts
left JOIN wp_term_relationships AS thistag ON (thistag.object_id = 2376 )
left JOIN wp_term_relationships AS tagrel on (tagrel.term_taxonomy_id = thistag.term_taxonomy_id
AND tagrel.object_id = wp_posts.ID)
left JOIN wp_term_taxonomy AS tagtax ON ( tagrel.term_taxonomy_id = tagtax.term_taxonomy_id
AND tagtax.taxonomy = 'post_tag')
left JOIN wp_term_relationships AS thiscat ON (thiscat.object_id = 2376 )
left JOIN wp_term_relationships AS catrel on (catrel.term_taxonomy_id = thiscat.term_taxonomy_id
AND catrel.object_id = wp_posts.ID)
left JOIN wp_term_taxonomy AS cattax ON ( catrel.term_taxonomy_id = cattax.term_taxonomy_id
AND cattax.taxonomy = 'category')
where (post_status IN ( 'publish', 'static' ) and ID != '2376') and post_password ='' and post_type = 'post'
group by id
having score >= 3.00 order by score desc limit 5 on duplicate key update date = now();

This was on a machine that had plenty of resources available and this query ran for 1214 seconds and ended up examining 485~ million rows.  This is an extreme case but an example of what we see on a regular basis.  The typical cases are more around 15-30 seconds with 5-10 million rows examined.  Even then this is just not reasonable for shared web hosting environment.  All it takes is a few posts and these will be stacking for quite a while.

This of course all could be avoided by assuming the end users of the plugin need to be saved from themselves.  The least impact settings being used by default and more advanced users can setup more in depth and CPU time consuming features.

Simplepie

This one has been a thorn in our side for a while now so I needed to mention this one as well.  This plugin is notorious for creating large numbers of tiny files in its cache folder.  Unfortunately no one thought that it would be wise to have some sort of cleanup mechanism built into it.  We tweeted about this a while ago and were suggested to run a find command to remove old entries.  Unfortunately though this is the sort of thing that just does not work well when you’re dealing with thousands of end users without the knowledge to be doing this.  So this means for the majority who run this plugins they never clean up the caches.  We have seen caches grow to hundreds of thousands of files over a period of time.  Anyone who has seen a lot of tiny files in a single folder knows just the kind of problems this can start creating.  From the performance stand point looking up the folder becomes much more intensive due to the sheer number of files.

So unfortunately our solution for users we find with intensive usage coming from this plugin is to simply disable it.  Expecting the end users to configure and setup outside mechanisms to keep the plugin under control is just not reasonable.  Just like the YARPP plugin the assumption should be that the user is not very technical.  That means addressing problems for them so in this case it means having a cleanup mechanism built into the system and any other configurations to create least impact.

Auto Posting Plugins

I feel like this is one where there is no point even bothering to point out specifics like WPRobot because if it’s not that plugin it’s another similar to it.  These plugins are notorious for running frequently and the only solution is reducing the amount of times they scrape content and post.  It’s not a case where we can say end users aren’t allowed to run them, as they’d just find another host who will allow it.  So no matter what there is going to be a CPU hit that I’m sure most would prefer to avoid.

There are some points of contention about these plugins and the kind of problems they create with their use.  One is the sheer number of posts they create causes the amount of time bots spend on the site to increase dramatically from a normal web site.  You can reduce the impact by modifying the robots.txt file to tell the bots who respect this to slow down a bit.  Unfortunately though it’s not going to stop the scrapers from hammering a web site with no regard to the server.  The effects are amplified because some of the WordPress core itself that has some functionality just not designed around having a large amount of posts.

The use of SQL_CALC_FOUND_ROWS by WordPress makes sense with a few posts and the query can be as fast or faster than a combination of count() for number of rows and select for the actual dataset.  So this is what typically ends up happening:

# Time: 101128 18:55:07
# User@Host: username_wordpress[username_wordpress] @ localhost []
# Query_time: 24.974943  Lock_time: 0.014747 Rows_sent: 15  Rows_examined: 56864
use username_wordpress;
SET timestamp=1290992107;
SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish')  ORDER BY wp_posts.post_date DESC LIMIT 0, 15;

The initial query from this will take 10+ seconds to run or longer depends on the size of the dataset.  Also typically see some sort of lock time due to the insertion of new rows by the auto blogger always happening.  We run this query again it’ll hit query cache and be fast but the problem is it’s unlikely to be hit again for quite a while.  So what you end up with is a different query each time so you’ll never hit a cache. It is a frustrating problem and these auto posters have now made an even bigger case to scrap the use of SQL_CALC_FOUND_ROWS in all cases in the wordpress core.  The gain from it on small datasets is just not worth it when larger datasets the performance penalty is drastic.  This auto posting though just does not affect the core it affects the plugins as well.

A lot of plugins are under the assumption of small datasets.  So the YARPP example I gave was actually pulled from an auto blog plugin – YARPP is typically fine with smaller datasets. Unfortunately the majority of cases the dataset is quite large.  It’s not just YARPP though the sitemap generators all assume small amounts of data.  So the sitemap generators some of them scrape the actual web site.  So it’s not surprising to see one cause several hundred thousand pageviews a month due to the sheer number of posts it’s attempting to scrape for the sitemap.  It also affects the caching plugins as they become pretty ineffective when a post might only get visited twice a day if it’s lucky.  It then creates ineffective caches in most cases unless you modify the caching plugin to not purge caches.  Though like I said most users do not modify the caching plugins in anyways.

SEO Booster

This one is a new one for us to see but has already made a name for itself as a plugin we dislike and it enjoys frequently causing lengthy 10+ second queries.  It’s always the same query so here is an example:

# Time: 101128 16:32:19

# User@Host: username_wordpress[username_wordpress] @ localhost []
# Query_time: 11.884008  Lock_time: 0.011632 Rows_sent: 1  Rows_examined: 358304
use username_wordpress;
SET timestamp=1290983539;
SELECT * FROM `wp_seobooster` WHERE ((`SePosCheck` < '2010-11-27 22:32:08') && (`SeRef` LIKE '%google%') && (`SePage`<8) && (`SeQuery` NOT IN (''))) order by `SePosCheck`, rand() ASC limit 1;

It’s use of LIKE %google% is the troubling portion.  Running searches like this is not very friendly to run.  Do this on a table with a few hundred thousand rows and watch as it takes significant time to run nearly every time it’s not sitting in a cache of some kind.

So is this a plugin really worth running?  Probably not it’s pretty slow when you start dealing with more traffic.

Misc Stats Plugins

I’m not a fan of the stats plugins as they do not make a lot of sense to me.  Sure it’s cool to be able to see how many views a post got via the WordPress admin page or displayed to the end user but is there any actual gain though for improving the WordPress installation / is it worth the overhead?  Not really, you can get these same stats from any stats service.  Awstats, Webalizer could provide basic stats and if you want something more in depth then use of Google Analytics.  It offloads the stats from your WordPress installation. It’s also a lot better than have a 1GB stats table that’s constantly getting hit with queries.

Misc Rants

I’ve touched on various plugins and I’m sure there are many more to talk about but I wanted to cover just some major ones and major categories of plugins we see at Hawk Host.  Plugins aren’t the only culprit however – the use of poorly thought out themes has also become a problem as well.  You can install any theme with a click of a button without knowing what sort of performance hit you will take for running them.  A lot of themes are great but there are some out there that just do not understand how everything works and thus cause performance issues.

An example of some are the ones that make all their CSS, JS, etc files into .php files for no reason.  So the code may look something like this:

<?php
// main page css file
?>
css code goes here

Replace that with JS or something that is normally a static file.  What the theme developer does not realize is they are causing PHP to be loaded for each request to that CSS or JS file which is significantly slower than simply requesting a static file.  So what you end up with is where each page load of the WordPress installation might have to load up 5 PHP processes to serve that single page when all it required was one.  It’ll take one for the actual WordPress installation then a bunch of them for all the CSS/JS files.  They may do nothing so the CPU hit is minimal but you’re still having to launch extra PHP processes.  So if each PHP process take 20MB of memory we’ll say (which is pretty modest) the wordpress blog would go from needing 20MB of memory per request up to 100MB. As you can imagine this behavior isn’t optimal and can cause issues pretty quick. This isn’t limited to static files – thumbnail generators are similar when they convert images on each request.

You also have themes with dependency of certain plugins so you’ll run into a theme requiring 5 plugins. Unfortunately the theme author rarely takes into the account of the actual performance of the plugins required and ultimately sacrifice the quality & speed of the blog. Unfortunately the average end user doesn’t usually consider this either.

This has created a problem that a lot of providers have now.  The majority of users not knowing how to use FTP or how to configure things but having WordPress installations with 40 or more plugins.  There are plenty of high quality plugins but they’re simply not configured properly. For example the majority of W3 Total Cache installations the user is running it in preview mode which isn’t really caching anything.  Or for WP Super Cache it’s missing mod_rewrite rules or the cache is broken entirely.  We actually created articles to address these when suggesting to users to use the plugins:

How do I install W3 Total Cache?
How do I install WP Super Cache?

This is just a small window into the problem though and I by no means addressed the majority of plugins we see problems with.  It’s not just certain plugins but having too many installed creating a wordpress blog that runs 300 queries to the database per request.  I don’t see how this can possibly be addressed by WordPress unfortunately.

They can improve the core slightly like stop making use of SQL_CALC_FOUND_ROWS but that is something that is only touching the tip of the iceberg. Ideally educating the WordPress user base about performance penalties of plugins and drawbacks would be a great step in the right direction unfortunately I do not see it happening. Perhaps it would be wise to put a warning page and a brief disclaimer on the plugins page warning users that installing too many plugins may cause performance issues or maybe adding something to the core of WordPress to measure the performance and overhead of plugins and giving the user the ability to actually see the drawbacks of certain plugins (measuring page load before, after, etc). Unfortunately a lot of users don’t notice that their WordPress installation is significantly slower than a normal WordPress installation or they don’t draw the parallel as to why it’s slow. Though these are just ideas time being and we’ll all just deal with the problem.

This means system administrators will continue to warn their end users of the problematic performance of their wordpress installations.  The answers as to why will be limited to simply suggesting disabling the various intensive plugins.  If the user chooses to ignore the warnings they find another provider or they upgrade to higher plans all so they can run a plugin that provides minimal gain.  It’s unfortunate that it’s turned into this but it is what it is.  Web hosts, system administrators and anyone else dealing with hosting wordpress installations can just hope there is a plan to address this growing problem.  It is tarnishing WordPress in terms of performance and even puts the provider in bad light when all they can offer is an umbrella statement saying it’s a plugin they’re running.  It is no heavier than various other applications out there it’s just all the easily installed plugins with no metric to measure their impact that is hurting their reputation with system administrators.

This entry was posted in General, Programming, Tips. Bookmark the permalink.

4 Responses to WordPress Performance

  1. Syamsul says:

    Thanks for the informative post.

    Perhaps in your welcome email to shared hosting customers, a link could be included to a section on recommended WordPress plugins and settings etc in the knowledgebase

  2. Hikari says:

    I count on WordPress issues.

    I’ve been complaining in WP community about plugins quality and how developers are handled by users and WP owners.

    I develop my plugins and have around 70 plugins on my main site, but I try to care about performance and developed my own cache plugin that made my database queries go from 300 to 70, and load time from almost 8min to less than 3min.

    Of course I don’t have time to make my plugins perfect and test all plugins I use, but I’m trying to make it better. Many sucking plugins I used I just forked and made my own, much better than original.

    The one big thing when we talk about WordPress performance is caching. It has a relatively good cache standard, that developers can use and plugins can be created to enhance.

    It’s sad when we see a plugin that makes database queries everytime a page loads, and get always the same result. They could put that data in cache and load from there, saving a lot of resources. And even when data changes, there are times that we don’t need it perfectly updated, so we can cache and use outdated data and only update from time to time.

    Now, my real problem is with storage space. I don’t know how I spend so much in file storage. I know my wp-content backups take some, but if I don’t keep deleting files they just grow, and I have just a little space left. There should be a tool to show folders size, so that I could find where all this space is being used. I wanted to make a full backup of my account, download local and search, but I don’t have the time for that and neither space to save a full backup.

  3. Hikari says:

    I really don’t like the idea of warning users about plugins. Users that know about performance don’t need that warning, we use bad plugins because we need them and we do what we can to handle problems.

    But, noobs who you’re talking about simply don’t know what to do, and that kind of warning would make things even worse for us plugin developers!

    It’s already too much see “do it without plugins” tutorials, users don’t like us and WP owners wanna use our free work and take our plugins. We don’t need to be seen as an enemy, get users scared of us, or anything like that. Seeing an irresponsible warning would make them think all plugins are bad and just remove them all.

    I also don’t like tools to vote for plugins. What could be done is complainers contact plugins authors and suggest how to improve them. Remember that many plugin developers are still learning, and their published plugins are just idea suggestions.

    In this post itself there are some ideas of how to improve things. It would be nice to add comments to plugins pages and track tickets, reporting problems to who should know about them and saying how to make it better.

    Instead of just complaining and pointing fingers, we must help each other improve our work.

    Measuring ideas are good, but they must be aimed to developers and not users. And they already exist, we can see how long a task takes to run and how much RAM it’s being used. My Hikari Hooks Troubleshooter helps in it a lot. 🙂

  4. Kent says:

    Thanks for this post, Hawkhost, it’s very much appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *