If your website is slow then people will either get annoyed with it or simply not visit it. Bottom line – you can lose money.
I met Donncha in real life for the first time a few months ago and one of the things that I was anxious to talk to him about was WordPress’ speed or lack thereof, as both my own sites and those of clients etc., seemed to suffer from performance issues.
This site has been known to do over 100 gigabytes of transfer in a month, so performance can become an important factor.
Donncha, who works for WordPress fulltime, was adamant that WP itself was not to blame. As I had previously suspected the culprits were badly written plugins.
Unfortunately this is one of the downsides to PHP.
It’s simply TOO easy to write bad PHP code. If even I can release a modified plugin (and I cannot program to save my life) then you know what I mean!
Evaluating Performance
Prior to the reinstall on this site the number of SQL queries per page was outrageous, with some pages requiring well in excess of 100 SQL queries to render!
If you look in the page footer now you can see that it’s been cut back significantly.
Server Side Options
On the server-side I’m using MySQL 4 – simply because it ships with Ubuntu. The Ubuntu config includes some caching already, but the max clients setting had to be increased significantly, as the server would become either slow or simply unresponsive at least once every 24 hours. The fix for that was simply to “borrow” a config from a much busier server π
On a sidenote. If your site is really important to you and is a major source of revenue, be that direct (sales / affiliate sales / advertising revenue) or indirect (such as business referrals worth thousands of Euro) then going dedicated or at least semi-dedicated is the only sane option. You simply cannot run an important site in a shared environment.
Apache could be optimised further by simply removing unwanted / unneeded modules OR, as some people have suggested, by replacing it completely with a lighter HTTPD.
Php could be sped up using a caching mechanism. As none of the open source PHP caching solutions seem to be available as Debian / Ubuntu packages I have decided not to try this method as yet, however, if anyone has done so I’d love to hear about your experiences.
Instead of upgrading the backend, and leaving loads of old files lying around the place, a clean slate definitely helps.
Now, in my case, getting a “clean slate” was not intentional, however it has paid dividends.
If you cannot think of a valid reason to use a plugin, then you can probably do without it. There is no reason to have more than a couple of plugins enabled. If you need tons of plugins then you probably should consider using something else or maybe writing your own software…
One of the plugins I find particularly useful is Brian’s latest comments, however the “stock” version is rather heavy, as it generates SQL queries on each and every page load. Donncha “WordPress” O Caoimh rewrote it so that it’s a hell of a lot saner.
(thanks!)
Another plugin that was worth enabling is Wp-Cache. The latest version includes some improvements supplied by Mr O’Caoimh π
What both of these plugins do is create static files on the physical disk instead of relying on MySQL to do all the work. (This is one of the reasons why some sites such as search.ie or blog.blacknight.ie use the Perl scripts that they do!)
I’m not sure what else I can do at this point to speed things up, as I’ve effectively taken the number of SQL queries per page from an alltime high of about 110 to about 30 (or less)
If anyone has any other suggestions I’d love to give them a go
Donncha O Caoimh says
Try memcached, it caches get_option() calls really well. Apparently the improvement for a single WP blog isn’t worth using it but I use it on my blogs because I think it does help.
You really should use a PHP accelerator. It really well make your pages snappier, especially now that you’re using wp-cache and the db won’t be hit as much.
Make sure you’re using the MySQL Query Cache. The new WP2.1 makes great use of that!
Use monit to monitor and restart Apache when/if it starts to leak memory or get hung.
I really should write a post about this too..
michele says
Donncha
I found a package in Ubuntu for memcached, but there’s no specific reference to php. Is that all I need?
Which PHP accelerator would you recommend?
This server has more than one blog on it π
MySQL already has caching as far as I can tell
As for monit – I will explore
M
Donncha O Caoimh says
I mentioned in my talk at BarCamp that the version of memcached packaged in apt is slightly out of date. You should find the tarball and compile it yourself because it works better. Google for “memcached wordpress” or for variations on “objectcache memcached” as Ryan Boren created a caching plugin.
If you’re running multiple blogs it may need patching because last time I tried it it stomped on the settings of other blogs. I think I added the SERVER_HOST or something to the cache key to make the caches site-unique.
I use Eaccelerator, works well out of the box and easy enough to install once you follow the docs!
michele says
Cool π
I’m an Aquarius though, so I’m not too sure how well instructions would work for me π
Niall says
Michele,
I’ll have the phone off when you want to sort out that mess π
Rob says
Another PHP problem, of course, is that, unless you use an accelerator of course, the whole application, or at least large parts of it, have to be parsed for EVERY SINGLE HIT. This becomes very obvious with the Ruby-on-Rails copies written in PHP, which are generally painfully slow.
Possibly using Apache’s proxy module, or Squid, set to ignore No-cache but expire every 10 minutes or so, would work. Most of the traffic will then get no further than the proxy.
I take no responsibility if this causes your website to catch fire π
michele says
Rob
So some form of accelerator would help with any php driven sites?
Robert Synnott says
It should, yes, to an extent. It won’t help with SQL slowness, though, just PHP slowness. As Donncha says, memcached will help with SQL. The proxy thing would work, but it would make the site appear less dynamic.
michele says
Rob
With memcached installed do I need to tweak anything on the php-side?
As I’m using Ubuntu I’m trying to stay with the official packages as much as possible π
Michele
Robert Synnott says
RE: memcached tweaking – yes, very much so. WordPress would have to be written to take advantage of it, more or less; I hadn’t realised it was, but from what Donncha says I assume it is, somewhat. Google turns up vaguely promising things.
John Handelaar says
One thing that’s basically free is to use APC (`apt-get install php4-pear`, then `pecl install apc`) and edit apc.ini in /etc/php4/conf.d to taste.
You can remove all the disk accesses and PHP compilation involved in every page request by loading the whole app into RAM.
And ferchrissakes don’t be using MyISAM tables in MySQL.
> ALTER TABLE tablename TYPE = “InnoDB”;
…for anything which gets written to a lot. Comments, trackbacks (think spam) and anything which logs page views will choke very quickly under load if you’re using an engine which:
a) Stalls all reads until the updates are done and
b) Stalls those updates until all the reads before it are finished first.
Race-conditions-a-gogo. More memory won’t help much.
FWIW on the missus’s 200K pages per month Second Life blog, I gave up on wp-cache after three hours of trying to make it not crash and burn horribly and/or segfault Apache. And you’re not allowed to gzip output when it’s turned on.
My suggested lightweight not-Apache, for those not party to our conversation in Waterford, was nginx. I’m a Debian nut myself (and it’s in apt) but I opted for a dramatically-newer version. It compiled in about 15 seconds and lives in the not-very-hostile /usr/local/nginx, and doesn’t drop init scripts *anywhere* else.
My details (which relate more to Drupal, even though the aforementioned SL blog is WordPress) I posted here, and the config file pr0n is on Drupal.org.
Oh, that reminds me. This would be my email address, Michele.
Casey Woods says
I’m a big fan of the APC cache. We installed it on a really high traffic Vbulletin site and it reduced the server load by at least half. I’m running it on my WordPress site and it certainly seems to have speeded things up. Not WordPress specific, but a great option if you are an admin on your server. Really easy to install using PEAR.
michele says
John / Niall
I’ve installed apc on one server and am going to put it on here shortly (ie. later this evening)
Is there any way to see what the cache is up to?
Michele
John Handelaar says
It comes with a file called apc.php (`locate` it, should be in the slocate db by now) which you’ll want to edit (to add authentication) and copy into the web tree of the site in question.
Graphs, stats and lots of other stuff aplenty when you call it from a browser. Chances are it’ll not be using the user cache (you need to code that into an app) but the system cache’ll hum along nicely.
Definitely use it to get a feel for what memory use to assign.
michele says
John
Excellent π
Any ideas on why it would install and work perfectly on one server but give unhelpful segfaults on another (this one)?
Where can I begin to look?
Michele
John Handelaar says
What’s segfaulting? The cache module or the apc.php script?
E_ALL error reporting might turn up something useful in your PHP error log (note: enable that) if it’s the former.
If it’s the latter I’d run it on the command line with strace around php4-cli to see what strace has to say immediately before bombing out.
Of course I’ve been assuming you’re *not* using apt to install APC – I’ve always done ‘pecl install apc’ after sorting out the apxs/apxs2 symlink to avoid its failing. There is, however, a php4-apc package in apt. One thing to try is whichever the one you’re not doing now is.
John Handelaar says
Oh, and check that the funky-ass apt Apache2 config isn’t trying to load all the php modules twice. Oftentimes I see things getting dropped on the end of /etc/php4/apache2/php.ini *and* getting duped in conf.d/modulename
michele says
John
I’m using php5
Apache is segfaulting, so it’s simply not parsing any PHP at all !
I installed apc using the method you described – there’s no version available for apt π (or at least I couldn’t find it!)
I’ll check the conf.d to see if there’s anything odd going on, though it’s working fine on the other server I’ve installed it on and I enabled it there via php.ini
Michele
michele says
John
I’ve moved this site over to the server where APC is working π
Are there any particular configuration parameters I should worry about?
I’ve set apc.shm_size = 40 , but I’m not sure if I need to do anything else
Thanks
Michele
John Handelaar says
What I have for WP:
# configuration for php APC module
extension=apc.so
[apc]
apc.enabled = 1
apc.shm_segments = 1
apc.shm_size = 40
apc.optimization = 0
apc.ttl = 7200
apc.user_ttl = 7200
apc.num_files_hint = 1000
apc.mmap_file_mask = /tmp/apc.XXXXXX
apc.filters = wp-cache-config
Only the last one is apparently very important in WordPress. The TTL stuff expires cached entries after 2 hours.
michele says
John
As you’re the expert on this π
Is 40 megs enough? Should I up it more? There are a couple of sites on this server that get quite a lot of requests and they’re all running php (Apache hit maxclients again yesterday!)
John Handelaar says
(Sorry, was moving house.)
I’m running quite a few on 40MB, but all the Drupals are sharing the same installation – precisely to minimise cached memory use. Drupal’s about 9M, WP is about 3M iirc… my ballpark number would be to ‘du’ the parent dir of the nginx-hosted sites and feed it however many megs they’re using on disk.
But then I’m not a big host with hundreds of no-traffic domains: nothing I’m pushing through nginx is doing less than several hundred page loads per hour, and so I want all of them in RAM if I can. YMMV.
John Handelaar says
Oh, obviously that ‘du’ thing only works if everything in the directory is a PHP file (in Drupal’s case that’s almost true so I forgot to qualify it).
michele says
John
So you’ve got per vhost caching?
Sorry if I’m being a bit thick about this π
Michele