Over the 2 years of running WP Intense, I’ve had many questions from clients asking to review the performance of their website. In this article I’ll cover the most common issues and the easiest solutions to solve your performance and scalability.
Uncached versus Cached Performance and TTFB
Firstly, it’s important to understand why uncached performance matters.
The most common solution to scalability issues in any platform is to cache everything. Problems arise when it’s impossible to cache everything. This commonly happens when you have a lot of products and/or posts, and you have a lot of filters. It’s impossible to cache all the varieties of filters, so it’s important that your uncached speed is not killing your server.
When an uncached request consumes all your server’s CPU and disk for 10 – 40 seconds, it doesn’t only affect this one user – it affects everyone. If you’ve ever experienced your PC maxing out due to some large batch job you’re running, you’ll know this kind of pain already.
By fixing uncached performance, you make it far easier for your server to generate cached pages for immediate delivery to future users.
The first, and most obvious, issue is your hosting. If you’re on a shared server, you should really fix this before anything else. With the advent of the likes of Digital Ocean with $10 per month droplets, there’s really no good reason to be on shared hosting any more.
Firstly, shared hosting typically limits your MySQL connection counts. They might limit you to 10 connections, or if you’re lucky, you might get 50 connections. Regardless, you want NO limit.
Secondly, you have no CPU or DISK resource to yourself. That means two things – firstly, your performance is going to slow down intermittently based on what other users are doing on the server you’re sharing. Secondly, it means it’s incredibly difficult to identify performance bottlenecks when you can’t tell if it’s an issue with the plugins you have installed, or whether it’s just that another customer is abusing your server with a massive import job that’s consuming CPU and disk resource.
For good hosting, I recommend any of:
- Digital Ocean – if you have some technical capabilities, this is the cheapest option with the best bang for your buck. There are a variety of stacks you can install, and Digital Ocean gives you total control over your WordPress environment.
- Cloudways – these guys provide a managed service on the Digital Ocean environment. If you need managed support, this is the second most cost-effective method of getting good hosting.
- WP Engine – if you want real hand-holding, and don’t want to think about your stack or WordPress technical environment at all, WP Engine are a solid choice
Good Server Stack
If you’re still using PHP 5 or MySQL, you have a poor server stack. Top of the range looks something like this – you can speak to your current hosts and ask them if they can provide it:
- Nginx instead of Apache
- Redis or Memcached instead of no memory-based caching engine (or instead of disk caching)
- PerconaDB or MariaDB instead of MySQL
- Varnish or Nginx fast cache instead of no micro-caching or short-term page-caching solution
- SSD instead of HDD
- PHP 7 instead of PHP 5
- Fail2ban – this beats WordFence on performance and security, no question. It solves security at the firewall level meaning any bots attacking your site consume ZERO resources on your server
- Letsencrypt SSL – Google cares about HTTPS these days and is starting to warn users that non-HTTPS sites are insecure. If you have users logging in, you MUST use HTTPS. Letsencrypt gives you free SSL certificates for life.
Too Many Queries
If you’ve fixed your hosting, or if you’ve skipped ahead to this section, one of the two most common WordPress-based scalability issues is plugins that have been installed which are causing far too many queries per page.
To identify if this is an issue you are suffering from, you should install Query Monitor by John Blackbourn. Once installed, visit your slowest page whilst logged in and look at the Query Monitor admin bar. For example:
There are 4 numbers that Query Monitor shows.
- Total page load time (in this case, it’s TTFB or Time to First Byte). In the example above, it’s showing 2.92 seconds TTFB which is quite slow (although it IS on a 850,000 product site)
- Total page size, in KB. In the example above, it’s showing 10MB page size which is quite large.
- Total MySQL time. In the example above, this is 2.36 seconds which is a lot, but it also tells us that the amount of time spent in PHP is 2.92 – 2.36 which is 560ms PHP execution time.
- Total number of MySQL queries executed on the page. In the example above, 54Q or 54 MySQL queries is very low.
So – if you install the Query Monitor and you see that you have a LARGE number of Q, for example over 100Q, then you have a plugin problem and you need to find the culprit.
Thankfully, Query Monitor provides an option to view queries by component. See this screenshot:
After you’ve clicked “Queries By Component”, Query Monitor will scroll down the page to something like this:
In the example above, there are no real issues. Fewer than 100 queries is totally fine for a WordPress page. But if you have a lot of queries, you’ll typically find 1 or 2 plugins at the top of this little table which identifies where all your performance is disappearing to.
If too many queries is the issue you’re experiencing, you’ll find that counter 1 above is showing a large time and counter 3 is showing a low time. This is because, when there are too many queries, the time to generate the page is bottlenecked by the speed of your PHP processor. More CPUs will help, as will PHP 7 instead of PHP 5 as it’s about 3 times faster at executing PHP code.
In any case, the most logical next step is to eliminate the plugin culprits.
On the other hand, if you have a low number of Q (fewer than 100) but the MySQL execution time is large, then the likeliest situation is that your MySQL database (or PerconaDB or MariaDB if you followed the first steps) is performing table scans. Table scans are the enemy of scalability. Basically, they typically mean that every item in the table is being read into RAM. This has multiple problems. Firstly, it causes all your MySQL cache to be wiped. Secondly, it causes your DISK to thrash whilst fetching all this data.
To solve this, you need to eliminate the table scans. This is specifically why I built Scalability Pro. If you have Slow Queries, Scalability Pro will solve your uncached WordPress performance.
Fix your hosting, then identify which type of scalability problem you have. If you have too many queries, replace the problem plugin(s) with superior plugins. If you have slow queries coming from your plugins, get Scalability Pro to solve your slow performance.
If, for some reason, Scalability Pro does not solve your slow queries, rest assured that my mission is to fix EVERY slow query that exists, working from the biggest plugin culprits downwards.
I’m looking forward to any questions or comments.