WordPress and performance. If one follows the ongoing battle between aficionados and adversaries of the most used content management system on the Web, the extremes could not be more pronounced. One side argues that the ecosystem surrounding WordPress justifies some trade-offs when it comes to performance – while the other argues that legacy code sustaining the CMS is dragging down the Web as a whole. However valid both of these arguments seem to be, I think that doing your homework can make your WordPress installation fly – to a surprising degree. So let’s roll and see what we can do 🙂
One of the simplest ways to ensure WordPress speed grandeur is to focus on the things that can clog down your web server: media files. Every page has loads of them. Images, videos and too many stupid GIFs. I know, I know – who am I to talk. But let’s face it: text is not the most satisfying content out there any more. But what to do if you already have exhausted all the common strategies of improving performance – such as using proper caching or optimising all images?
Offloading media to the rescue!
Offloading media means to save your images not only in the „/wp-content/uploads/“ folder – a.k.a. your web server – but also on a specialised service providing you with cheap storage and fast delivery – a Content Delivery Network or CDN for short.
But why – in the name of Tim Berners-Lee – would I waste any more of my hard-earned golden nuggets on hosting?
Anyone hosting websites on the cheap
Good that you ask. Because first and foremost your users will thank you for improved speed and better user experience – and Google will rank you better. If that alone does not tickle your buttons, then listen to this:
Spending money on offloading media and a proper CDN setup will actually save you some bucks as you scale up.
Lonely Austrian Nerd
Spending money to save money? No, I am not entirely crazy. Let me explain.
Let’s say you host the Website of a medium sized company aiming for signups to a service – and assume that you regularly send out newsletters which lead to spikes in visitors. These spikes turn your website sluggish – the reason why your conversions are down 25% in comparison to any normal day. That sucks, mate.
So how do we fix this?
Well, doubling server resources would most certainly take care of things. But it seems crazy to basically double server costs just to handle one spike every couple of months. Going static rocks hard when it comes to performance – but would also require a full rewrite of the Website.
I say let’s get rid of media. But not by getting rid of the images itself but rather offloading them to a CDN. For this Proof-of-Concept I ran a WordPress Multisite installation on a basic tier droplet of DigitalOcean ($5/month) using a managed database (MySQL, $15/month) – using flood.io to load test three pages with multiple images and 100 concurrent users – resulting in thousands of requests per minute.
Initial run without offloading media
I hear you say „are you barking mad? 100 concurrent users on a tiny droplet like that?„. Well – if caching is used (in this test I use the W3 Total Cache plugin), this fares relatively well:
So, what do we have here? As you can see by the lack of red, the rate of failed requests was actually 0 – so no failed requests at all. That’s good. However, what becomes painfully obvious is the influence of concurrency on response time – after the ramp up period the perfectly acceptable 250ms jump up to a „I-will-bounce-from-this-site“ 8500ms; a bloody disgrace to any professional Website. All in all, this should not come as a surprise – using a $5/month server to be bombarded with almost 2,500,000 requests a day (approx. 1,760 requests per minute) seems to go a bit overboard 😉
Performance of WordPress with media offloading to a CDN
New the moment of truth: how does WordPress fare when offloading all media to a CDN? Well, great. But before diving into the data let me explain what exactly I offloaded – so that you can judge the possible impact offloading media to a CDN can have for your WordPress installation.
First of all, I used DigitalOcean’s „Spaces Object Storage“ with a custom subdomain to offload media from my server. The process of uploading all media automatically to this object storage is done – quite unusually – not by plugin, but by using a combination of Lsyncd and s3cmd. But let’s not get distracted by the more exciting parts of this PoC and get back to the boring data 😉 – a post will follow on how to build a similar setup.
Same testing period, same ramp-up period – and most important of all, same amount of concurrent users. As you can see in the comparison above, the results are quite striking. Not only was the test able to run at a substantially higher transaction rate of 2,250 requests per minute – an increase of well over 25% – but also the response times decreased mindbogglingly: from a catastrophic 4.7 seconds to an average of 166ms. I cannot stress this improvement enough: while serving approximately 3,240,000 requests a day the response time decreased to an average of 3,5% of the initial reaction time – all at the negligible cost increase of $5/month.
How far can we push this?
So, now we have seen a direct comparison of WordPress running on a small server without and with CDN. We saw that offloading media to a CDN yields substantial benefits to anyone trying to squeeze out every inch of performance from good ol‘ WordPress.
Well – to be perfectly honest, this has nothing to do with WordPress itself. The reason why this works so well is simple: by offloading media to a managed service hosted somewhere else, there is no need for our server to flex its muscles. As the images are not loaded from the same host as WordPress, the web server (Apache in this case) does not have to work as hard due to fewer requests made (about half actually – but this greatly depends on your site/workload). Consequentially, with less requests the CPU does not need to work as hard, the memory does not fill up as quickly and the drives hum along softly as there are very few files to serve.
This is all great. But when are we finally going to break things?
Patience, young coder.
Alright – how far can we push this? Let’s give this another run – and triple the number of concurrent users to 300.
While it still amazes me that this setup can handle over 6.2 million requests per day without returning a single error, one thing becomes clear: with an average response time of almost 10 seconds we won’t be winning any medals from our customers. Nevertheless, this PoC strengthens my view that scaling WordPress is not only a matter of pushing more money to a better hosting provider but substantially depends on your ability to optimise.
Summa summarum
In this post we used Object Storage to offload our WordPress media. This enabled us to more than double the amount of concurrent users our server can handle – and still leaves some room for further optimisation, such as offloading CSS and JavaScript files, offloading minified files generated by T3 Total Cache, switching from Apache to nginx, …
Your Website experiences spikes and you want to save a buck while still being able to handle more users? Go ahead and use a CDN – your visitors will thank you with higher sign-up rates.
How do you optimise your WordPress installations?