How to troubleshoot WordPress performance

I spoke at WordCamp Halifax 2017 on how to troubleshoot the performance of a WordPress site. This is the companion article that I wrote for it. If you’re just looking for the slides, click here.

Have you ever had a client come up to you and ask why a WordPress page was slow to load? We’ve all had that happen at some point or another. Especially nowadays with the increased importance of page load times! (Everything has to be fast fast fast!)

But what do you do when someone asks you to fix such an issue? It can feel like you’re looking for a needle in a haystack. The issue could be anywhere. (It really can!)

So what can you do about it? Well, there are a lot of tools at your disposal. They can help you figure out what’s going on with the performance of your WordPress site.

That said, it’s one thing to know that these tools exist. It’s another one to be able to use them and interpret what they’re telling you. The problem is that it’s what you need to get to the root of a WordPress performance issue.

What’s a WordPress performance issue?

Let’s start by defining what we mean by a WordPress performance issue. There’s no official definition for it. But we can get a good idea by looking at examples of WordPress performance issues such as a WordPress site where:

  • Loading the homepage takes a while.
  • The site search is slow to return results.
  • Publishing a blog post works, but times out.

Or we could go with the even more generic situation where everything is just slow. This slowness is what defines a WordPress performance issue. In fact, it doesn’t matter if it’s specific to a certain situation or general. (But it does matter to us troubleshooting it!)

To the client, there’s a perception that WordPress takes too long to do anything. And this can cause them a lot of frustration. (And lost money!) This is what we need to fix at the end of the day.

Where can you find them?

Alright, so we know what a WordPress performance issue is now. But that doesn’t do us that much good when we’re trying to fix one. What we need is to know where to look to find these performance issues.

But first a bit of theory

The key to doing this is to know what happens when you request a WordPress page. This means everything that goes on between pressing enter in your web browser and it finishing rendering the page. There’s a lot going on between those two points!

That said, we don’t need to know every detail of what’s going on between those two points either. The diagram above is enough for us to have a good idea of where to look for performance issues. Let’s walk through it.

When you enter an address in your web browser, it’ll contact your WordPress server. Your WordPress server usually runs both your PHP application (which is WordPress here) and your database. But this can vary based on how you or your host setup the server.

Meanwhile, on the server, WordPress and the database communicate with each other. This back and forth will go on until WordPress finishes rendering the HTML of the web page. Once that’s done, the server sends the HTML back to your web browser.

Using the HTML that it got from WordPress, the web browser will then make more HTTP requests. These HTTP requests tend to be for CSS and JavaScript files as well as images. The web browser will do this until it finishes rendering the web page that you requested.

WordPress code

The first and most obvious location for a WordPress performance issue is in your WordPress code. It could be the code that you wrote for your client. Or it could be code written by someone else like a 3rd party plugin or a theme.

You also have to keep in mind that there are two sources of code performance issues. You have the PHP code which is still where most of the WordPress development takes place. But with the increased usage of JavaScript, you also have to consider the JavaScript code as well.

Database

Next, we have the database. It’s another common location for WordPress performance issues. More often than not the cause a database performance issue is one or more slow database queries.

WordPress can do dozens of database queries each time that you load a page. But it just takes one slow query for everything to fall apart. That’s why they’re often a cause of WordPress performance issues.

The WordPress database is also made-up of multiple database tables. These tables all have configuration options that can affect their performance. That said, database table performance issues only affect the queries done against them.

Server

The server (or servers!) that hosts your WordPress site can also cause WordPress performance issues. Performance issues caused by a server issue can be hard to diagnose. That’s because there are two elements to a WordPress server: the hardware and the software.

The other thing that can make server issues hard to diagnose is the level of access that you have to the server. If you host the WordPress site yourself, it’s not an issue. But most of us don’t host our WordPress server, we use a WordPress host. The level of access that you have to a server can vary a lot from host to host.

Hosts

And speaking of hosts, it’s not uncommon for them to be the cause of performance issues as well. There are countless ways that a host could affect the performance of your WordPress site. Some of them are out of their control, but most of them are.

That’s why picking a good host is so important. It’s easier to make the distinction between a problem with your host and a server issue when you have a solid host. You can just assume that your host isn’t the cause of the problem. (But it can still happen so keep it in the back your mind!)

Browser

Sometimes there won’t be any problems that you can find in the locations that we’ve seen so far. The last place that you can look for an issue is in the web browser. But, like with servers, WordPress performance issues that found in the browser can be hard to diagnose.

A web browser is a complicated piece of software. There’s a lot going on between when you request a web page and when the browser finishes rendering it. WordPress performance issues can crop up anywhere between those two points.

Tools used to diagnose WordPress performance issues

This covers most of what we need to understand about WordPress performance issues. Now, we can talk about the tools that you can use to diagnose them. And there’s quite a few of them!

It’s worth pointing out that there’s no single master tool that you can use. The tools that you have available will depend on the location of the WordPress performance issue. That’s why it was important to explain where you can find them.

Starting with the web browser

In general, you want to begin your diagnostic process with browser issues. They’re often the easiest to spot and the easiest to fix. It’s also where you’ll find the most important tool in your arsenal.

Web developer tools

These are the web developer tools that you’ll find in your web browser of choice. Since a lot of us use Chrome, we often just refer to them as “Chrome DevTools”. But they’re all pretty much the same so use the one that you prefer!

There’s a good chance that you’re already familiar with these web developer tools. They’re pretty much a mandatory tool for web development nowadays. But why are they so important for diagnosing performance issues?

This goes back to our earlier description of what goes on when you make a request for a WordPress page. The web browser does a lot of the work required to render that WordPress page. (Which makes sense since you’re viewing the WordPress page in a web browser!)

It makes the initial request to the WordPress server. The WordPress server does its thing and then returns the HTML of the WordPress page. The web browser then does the follow-up requests for all the additional files that it needs to render the WordPress page.

Network panel

With web developer tools, we can see all this back and forth from the “network” panel. (It’s the same name on all browsers.) This should be your first stop when troubleshooting a WordPress performance issue. The network panel lets you determine at a glance if the issue is with the browser or with the server.

Here’s a look at the network panel for a request to the homepage of carlalexander.dev on my local computer. There are quite a few things going on in that screenshot. Let’s take a moment to go over them.

The waterfall

The first thing you should look at is the waterfall of network requests to the right. This shows all the requests that the browser had to do to render the homepage. The length of the bars is how long it took to perform the request compared to the total time it took to render the page.

You want to scan the entire waterfall for long bars. These are the requests that the web browser waited for the most. In our screenshot, this was the very first request that the web browser made.

When the first request is slow like that, it tends to mean that there’s a problem with the server. You can confirm this by mousing over the bar and looking at the details. Here are the details for the request to the homepage of carlalexander.dev:

There are quite a few details when you mouse over a request in the developer tools. That said, there’s only one that stands out. It’s the “Waiting (TTFB)” bar.

Time To First Byte

TTFB stands for “Time To First Byte“. It measures the time that elapsed between two important points in the life cycle of an HTTP request. Those points are when the web browser made the request and when it receives the first byte of the response to that request.

“Time To First Byte” is one of the best metrics (if not the best metric) to look at to determine the performance of your web application. (WordPress for us!) But that’s only from the perspective of the web browser. “Time To First Byte” can’t tell us what’s going on the server itself.

That means, that we can’t use it to diagnose a performance issue on a server. But it did tell us that there’s a good chance that our performance is there. That’s why it’s good to know about it.

Summary bar

Last but not least is the summary bar. It contains a lot of useful information that you can use to diagnose problems. You can find the summary bar at the bottom of the “Network” panel.

HTTP requests

On the complete left is the number of HTTP requests that the web browser needed to make to render the web page. If you have a lot of HTTP requests, it can cause a significant delay to the rendering of a web page. When that happens, you want to look into ways of reducing the number of HTTP requests needed to render the web page.

That’s unless your server supports HTTP/2. HTTP/2 lets a web page have as many additional HTTP requests as it wants. If you’re evaluating a host, you should always look for one that supports it.

Data transfered

Right next to the number of HTTP requests is the amount of data transferred by the web browser. The more data you have to transfer the longer it takes to view a web page. And it’s even worse when someone is viewing your web page on their phone. (Never forget mobile users!)

You should aim for a couple of megabytes for the first request to a web page. That’s when your web browser hasn’t cached anything so it needs to request all your web page’s assets. By assets, we mean things like CSS and JavaScript files, but also media files like images.

That said, requesting the web page again shouldn’t transfer the same amount of data. That’s because your web browser should have a lot of assets cached the next time it requests the web page. If your web browser needs to transfer more than a few dozen kilobytes, that’s a sign that something is off.

DOMContentLoaded and Load

Now, let’s move to the right. On that side, we have DOMContentLoaded and Load. These are the timestamps of two important events during the request of a web page.

DOMContentLoaded is the event that fires once the web browser finishes parsing the HTML of the web page. Meanwhile, Load is the event that fires when the web browser finishes rendering the web page. The difference between the two timestamps is how long the web browser spent processing everything to render the web page.

You want to look at the difference between these two timestamps. It represents how long the web browser spent rendering the web page. A big difference between the two means that the web browser spent a lot of time rendering the web page.

JavaScript is often the culprit when this happens. You might want to look into optimizing the JavaScript code. Or you could try to delay it until the web page finishes loading.

Console panel

Another useful panel is the “Console” panel. It’s where you’ll see error messages and warnings from your web browser. This is especially true if your WordPress site uses a lot of JavaScript.

JavaScript errors and warnings are often what you’ll see on the “Console” panel. So if you see a lot of yellow and red on the “Console” panel, you should take a look at your JavaScript code! You can also use it to run custom JavaScript code by hand.

But even if you’re not using that much JavaScript, you might still see a lot of errors there. That’s because all HTTP errors that your web browser has with its HTTP request will appear there as well. That’s why it’s a good place to start when looking for performance issues.

Other panels

Web developer tools also has other panels that you can use to diagnose issues. Those panels aren’t as useful as the “Network” or “Console” panel. That said, they can come in handy depending on the situation.

Performance panel

If you still have issues with JavaScript, you can also look at the “Performance” panel. (Or “Timelines” in Safari.) This is a panel that displays a special timeline. The timeline shows you what your web browser is spending time on once it receives the HTML from our first request.

You can use it to find slow elements during the rendering of a web page. In practice, you won’t use this very often. It’s only useful if your WordPress site uses a lot of JavaScript. (For example, if you were building a single-page application with WordPress.)

Audits panel

The last panel that we’ll talk about is the “Audits” panel. Unlike the other panels that we’ve talked about so far, the “Audits” panel is only available in Chrome. But, as we’ll see in a moment, it’s not a reason to switch web browsers for this panel.

So what does the “Audits” panel do? Well, it’s another web page analysis tool. It can analyze a web page that’s already loaded or you can make it reload the web page and analyze it.

But what separates the “Audits” panel from the other panels that we’ve seen is that it can make suggestions. It can tell you things you can do to improve the performance of your web page. That said, you shouldn’t expect huge performance improvements from implementing them. More often than not, they’re just changes that are nice to have.

Web page analysis services

There are also two services that do the same thing as the “Audits” panel in Chrome. (That’s why you shouldn’t switch browser for it.) In fact, these services can analyze your web page as well or even better than the “Audits” panel. So what are these two services?

Well, the first one is the famous (or infamous!) Google PageSpeed Insights. This is one of the tools that Google offers as part of its suite of website performance optimization tools. It’ll make a lot of the same recommendations as the “Audits” panel in Chrome.

The other tool is Pingdom‘s website speed test tool. This tool can often be more useful than Google PageSpeed insight. That’s because it combines elements of the “Audits” panel with the waterfall from the “Network” tab. This gives you a better overview of the performance issues that your web page has.

The only limitation that these tools have is that they need to be able to connect to your WordPress site. This isn’t possible if you’re still developing the WordPress site on your computer. In that situation, the only tool that you can use is the “Audits” tab.

Moving to the server

At this point, you should have a strong idea whether the performance issue is with your web browser or not. If the issue isn’t on the web browser side, the only place left to look is on the server. Unfortunately, finding the issue on the server isn’t as easy as knowing that the issue is on the server.

The problem is figuring out where the issue is on the server. It could be with WordPress which means inside our code or with the database. Or it could be with the server itself.

But, as we saw earlier, there are two sources of performance issues with servers. You have the server software which is often either the database server or the web server. Or there’s the server hardware which is a bit harder to diagnose. (Often it’s high load due to limitations with the server hardware.)

Needless to say, pinpointing a performance issue on a server is a lot trickier than what we’ve seen so far. We don’t have too many tools that we can use to figure things out either. This increases the importance of being able to read what the tools are telling us.

Query Monitor

In general, it’s better to start with WordPress when looking for performance issues on a server. Most of us aren’t that comfortable with the servers so. It’s also a lot more common for the issue to be with WordPress than it is to be with the server.

The best tool for looking at performance issues with WordPress is a plugin called Query Monitor. If you don’t know Query Monitor, it’s the best debugging plugin for WordPress. Most WordPress developers use it during development, but you can also use it on a live site. (Just turn it off once you’re done!)

Query Monitor has a bit of a deceiving name. It doesn’t just monitor SQL queries as the name implies. It collects all sorts of information about the WordPress page that you requested.

You can see which hooks the plugin API called. Or you can view all the enqueued scripts and stylesheets. These are but a few examples of the type of information that Query Monitor collects.

SQL queries

That said, more often than not we’re going to use Query Monitor for its namesake. We need it to check to see if there are any slow SQL queries in the WordPress page that we requested. We can view this at a glance by looking at the admin bar.

The number on the left is how long PHP took to render the page. 1.38 seconds is a pretty long time to render a WordPress page. In general, you’re looking for a number in the 100s of milliseconds.

To the right, we have two other numbers. The rightmost one is the total number of SQL queries performed by the wpdb class. The number to its left is the time in seconds that MySQL took to perform all these queries.

We can see from this that MySQL queries only took 0.002 seconds out of the 1.38 seconds that it took to render the WordPress page. This means that it’s pretty safe to rule out SQL queries as the cause of the performance issue. We can start looking at something else.

Additional requests

A lesser known source of slowdowns is additional HTTP requests. When you make a request for a WordPress page, WordPress can make additional HTTP requests. Although these additional HTTP requests aren’t without possible consequences.

They can cause a significant slowdown in the rendering of a WordPress page if they’re slow. Lucky for us, Query Monitor also keeps track of the HTTP requests that WordPress makes. (Is there anything it won’t do!?) But there’s one limitation with it.

Query Monitor only collects information about HTTP requests made with the HTTP API. This means that, if someone is making HTTP requests without using it, Query Monitor won’t collect information on them. That said, the HTTP API is the recommended way to make HTTP requests with WordPress. It’s safe to assume that the HTTP API will perform most HTTP Requests for WordPress.

Above is a screenshot of the request section of Query Monitor. There’s quite a bit of information there. But, in practice, we’re only interested in two of the columns: “Response” and “Time”.

“Response” tells us what the HTTP response code for the HTTP request was. In this column, we’re looking for errors such as timeouts. These errors could be the reason for the WordPress performance issue.

Meanwhile, “Time” tells us how long the request took to complete in seconds. It’s not unusual for these requests to take a second or more. You need to ensure that the code making them is caching the response so they’re not happening all the time.

Database server processes

Let’s imagine that we’ve found out that we have a lot of slow queries. You can investigate things further by looking at the database server processes. Here’s a screenshot of server processes in Sequel Pro:

The two important columns to look at are “Time” and “Info”. “Time” tells us how long a process has been running. “Info” tells us what the process has been doing. If the process is for a query, you’ll see the slow query there.

Another useful aspect of database server processes is that they’re in real time. You can look at them as the issue is happening to other people. None of the other tools that we’ve looked at so far as let us do that.

But you don’t need a SQL client to view your database server processes. You can also view them using this SQL query: SHOW FULL PROCESSLIST;. The only annoying thing with using this query is that you’ll need to run it each time that you want to refresh the database server processes.

Additional server tools

Query Monitor and database server processes are the two most generic tools that you can use on a server. They’re available regardless of where you’re hosting your WordPress site. (There are a few exceptions, but it’s pretty safe to assume you can use them.) But, as we discussed earlier, not all hosts or servers are the same. If you have a better host or you have access to the server, you have other tools that you can use.

MySQL tuner

MySQL tuner is one of these tools. It’s a Perl script that analyzes your MySQL database serverand gives you suggestions. These help improve your MySQL database server’s performance and stability.

This can be a helpful tool when you’re having database issues that aren’t query specific. It’s possible that the issue is that your MySQL database server isn’t configured well. MySQL tuner can tell you that in a few minutes. All that you have to do afterwards is implement its suggestions and restart the MySQL server.

Slow logs

Depending on your server setup or host that you use, you might be able to view server logs. A few hosts let you view your PHP error logs which is useful when you have the “white screen of death“. But it’s not that useful for troubleshooting a WordPress performance issue like we’re doing.

What you want to use are slow logs. These are special log files that only contain logs about slow PHP processes or slow MySQL queries. With the exception of Pantheon, no other host has slow logs either enabled or available for you to view.

Application performance monitoring

The other server tool that you can use is application performance monitoring. There’s a good chance that you never heard of application performance monitoring before. It isn’t a tool that sees a lot of use in the WordPress community.

So what is application performance monitoring? It’s a service that you use to record and monitor the performance of your application. (The name makes it pretty obvious!) A good analogy for it would be “Query Monitor as a Service”.

But why isn’t application performance monitoring that popular with WordPress developers? “Query Monitor as a Service” sounds like an awesome service! (I know I wanted to build it!) Well, there are two important reasons why they’re not popular with WordPress developers.

The first one is that you need a high-level of access to your WordPress server. Most application performance monitoring services use a server agent to record application performance. If you can’t install the server agent on your WordPress server, you can’t use.

But let’s say that you could install the server agent on your WordPress server. There’s still another big problem with most application performance monitoring services. It’s that they don’t record any useful WordPress information like Query Monitor would.

New Relic

So why even bother talking about application performance monitoring services? Well, like most things in life, there’s exceptions to the rule. One exception to this rule is New Relic.

New Relic is the poster child company for application performance monitoring. (You might have even heard the name before!) New Relic is one of the few services that does an effort to collect WordPress specific application information. It collects information about the performance of hooks, plugins and themes.

New Relic has a really complex pricing system. So it might not be worthwhile to pay for it. That said, if you’re using Pantheon as your host, they offer it for free. They also have a great guide to help you troubleshoot WordPress performance using it.

Reviewing the process

Ok, so we’ve seen a lot of tools and theory! Let’s do a recap of what the tools that we’ve seen and how to interpret what they’re telling you. We alluded to it a bit, but we haven’t looked at it in any detail. A good way to do that is with decision flowcharts!

Console panel

In most scenarios, you’ll want to start by opening the “Console” panel in your web developer tools. You want to check if there are any errors or warnings. If there are any, you want to ensure that they’re not performance-related.

If there are performance-related errors or warning, you should try to fix them. If this solves the performance problem, then you’re done! Otherwise, we have to move on to the next tool.

Network panel

The next thing to look at after the “Console” panel is the “Network” panel. You want to scan for long bars in the waterfall diagram. Your initial focus should be on the first HTTP request sent by the browser. (Or the second HTTP request if the first one was a redirect!)

If that first HTTP request has a long bar, you need to look at the request details of the HTTP request. If the “Time To First Byte” bar is also long, then there’s a good chance that your issue is on the server. Otherwise, it could be a connectivity issue or something more obscure.

If the issue isn’t with our first request, we have to move on and look into something else. The number of requests that your web browser needs to make to render a web page is a good place to check for issues next. If you have to do a lot of requests to render your web page, you should look into reducing the number of them. This might still be desirable even with HTTP/2 since HTTP/2 only works with requests to the same web server.

You also want to look at the amount of data transferred by your web browser. If your web browser needs to transfer a lot of data to render a web page, you’ll want to find ways to reduce it. You can do this several ways depending on what’s causing the data transfer issue. But, in general, you can do solve it by using either a caching plugin and/or an image compression plugin.

If your WordPress site is still slow after fixing these issues, you can still use tools to analyze the web page. There’s the “Audits” panel that we saw earlier as well as web page analysis services. You can try to implement the changes that they suggest there and see if it solves the issue.

Query Monitor

At this point, we’re now looking at issues on the server itself. Our main source of performance issues on the server is slow MySQL queries. We look for those using Query Monitor.

If you have slow queries, you need to look into ways of fixing them. You could do this by using a persistent caching and persistent caching plugin. Or you could try to optimize the query or the code around the query to reduce the time it takes to run it.

If you don’t know how to do this, you should ask for help from places like the Advanced WordPress group on Facebook. (We’ll talk more about this in a bit!) If you do fix all your slow queries and there’s still a performance issue, then you want to move on to your server. (That’s if you have access to it.)

Server

When you log into a server, the first thing you want to do is look at the server load. If the load is high, you might want to look into upgrading your server. What do we mean by that?

After all, upgrading your server is a pretty vague directive. You could upgrade to PHP7 if you’re not on it already. (You can ask your host to upgrade you if they support it.) You can get a larger server with more CPUs and more RAM.

If you’re hosting your WordPress site yourself or on Pantheon, you can look at your slow logs. Fixing the issues in your slow logs might do the trick and fix your problem. But it’s possible that it won’t either.

Still stuck? Ask for help!

While pretty comprehensive, this article didn’t cover every possible cause of WordPress performance issues. (You’d need a book or a guide for that!) That said, it should help you solve the most common ones that you’ll encounter. If you’re still stuck, you shouldn’t hesitate to ask for help.

WordPress performance issues can be quite complex. There are people with experience out there that can help you get to the bottom of things. Don’t forget that this can be a useful troubleshooting tool as well!

Slides