Diagnosing admin-ajax.php Slow Responses in WordPress
With each CMS platform comes its own unique issues that you have to troubleshoot and deal with as a web developer or business owner. While WordPress might be the most widely used CMS, with hundreds of thousands of plugins and themes available, this also can result in it being one of the trickiest to optimize correctly as there are so many different variables that could be introducing delays. If you have ever run a website speed test on your WordPress site, then you have probably encountered references to admin-ajax.php
showing up in your results. Today we want to briefly explore how to better diagnose admin-ajax.php
slow server responses and what your options are as a WordPress site owner.
What is the admin-ajax.php
file?
In WordPress 3.6 the WordPress heartbeat API was introduced to allow WordPress to communicate between the web-browser and the server. It uses /wp-admin/admin-ajax.php
to run AJAX calls from the web-browser to keep track of what is going on in the dashboard. For example, if you log in to your WordPress site, you will immediately see a request for admin-ajax.php
in your logs. The benefits of this are improvements upon session management, revision tracking, and auto saving.
WP heartbeat API from the Make WordPress Core development team:
Initially it will be used for autosave, post locking and log-in expiration warning while a user is writing or editing. The idea is to have a relatively simple API that sends XHR requests to the server every 15 seconds and triggers events (or callbacks) on receiving data. Other components would be able to "hitch a ride" or get notified about another user's activities. This can be used to block simultaneous editing of widgets and menus or any other tasks that require regular updates from the server.
There are two different types of issues that can cause admin-ajax.php
slow server responses. The first is a backend CPU issue and the second is more of a frontend issue where you will notice third party plugins polling this file in your website speed tests. There was also a slight update from the core team in WordPress 4.1 to improve the "go to sleep" and "wake up" functionality, but a lot of people still seem to be experiencing issues.
admin-ajax.php
backend CPU issues
The first issue we encounter is on the backend. The pulse from admin-ajax.php
is only around 98 bytes, which is very small. However, over time this begins to add up. A lot of people run into backend performance issues when working with cheap and shared web hosts who have CPU restrictions in place. WP Tavern experienced this problem first hand and had to migrate hosts. Be sure to do some research into which WordPress hosting service is best before making a final decision.
InMotion Hosting wrote a great article on how the Heartbeat API affects your CPU loads. Basically, they logged into their WordPress dashboard and watched the access logs. They noticed that with the dashboard in focus the requests were spaced out to every 60 seconds. With the dashboard out of focus, the requests were spaced out to every 120 seconds. This is a lot of requests if you just left your dashboard open.
And each POST
request had a corresponding PHP script execution on the server using CPU time. They left their dashboard open for 30 minutes and there were 25 PHP script executions with a total of 5.77 CPU seconds.
And that was just one user. If you have multiple people logging into your WordPress backend the number of requests from the API increases simultaneously.
Heartbeat Control plugin
So how do you fix this? Well, Jeff Matson, a WordPress developer, created a great free WordPress plugin called Heartbeat Control to manage the frequency of the heartbeat API. You can also disable the heartbeat APi entirely if you want, however we don't recommend doing this. You can download Heartbeat Control from the WordPress repository. Once you install it you can find it in your dashboard under "Settings."
On the Heartbeat Control configuration page you have the following options for heartbeat locations:
- Modify heartbeat
- Disable heartbeat
- Modify heartbeat
You can also change the location where you want the above heartbeat settings to effect such as:
- WordPress dashboard
- Frontend
- Post editor
You can then change the frequency from 15 seconds all the way up to 300 seconds. By changing the interval to 300 seconds you are less likely to experience server performance issues.
admin-ajax.php
slow from third party plugins
The second issue we run into is third party plugins utilizing admin-ajax.php
for certain AJAX functionalities such as firing up popups or social counters. Some plugins make tons of POST
requests to this file which add up super quick. How can you diagnose which plugins are using admin-ajax.php
? Well, one quick way, without digging through a bunch of code, is to fire up up Chrome DevTools and look at the individual network requests.
First example with WP Notification Bar plugin
In this example below we can see there is some waiting time after DOMContentLoaded.
Just because there is a request doesn't mean it is necessarily slowing your site down, as some things can load asynchronously. AJAX loads after the page loads, but it is still not efficient when plugin developers are making tons of requests. Even when using AJAX great care should still be taken to minimize the number of AJAX requests that are employed.
Then take a look at the "post form action" on the HTTP response header. In our troubleshooting the plugin almost always reveals itself in the name of the action. For example, you can see the action is mtsnb_add_impression
.
If we do a quick search in the source code on the page we can quickly see the class with mtsnb and now we know from that it is our notification bar plugin at the top of my page polling admin-ajax.php
. Also the form data bar_id
is another hint.
Also, we can see it is also setting the cookie variable, as seen in the plugin options too.
You can then disable the plugin for a minute, run additional speed tests and confirm that those POST
requests to admin-ajax.php
no longer appear. It also is important to note that caching plugins typically won't cache admin-ajax.php
because it is inside the wp-admin directory.
Second example with Monarch Social Sharing plugin
In this second example we actually used GTmetrix. As you can there were 5 individual requests being made to admin-ajax.php
, after DOMContentLoaded.
If we dig into the Post tab we can see the action name get_shares_count
, which obviously leads us straight to our social media sharing plugin Monarch.
We have done this many times and thankfully the post action almost always matches the class, name of the plugin, etc. So with some connecting the dots you can quickly diagnose what is causing it. Sometimes the response header can also give you a clue.
Then to fix the issue it sometimes involves reaching out to the developer to see if they can load in a more efficient way with less AJAX calls, or perhaps there is nothing that can be done. If that is the case, you might want to weight your options or search for an alternative plugin. We have seen plugins that make 6-7 AJAX calls and then find an alternative plugin with the exact same functionality that does it in 1. So part of it comes down to how the plugins are developed and you should definitely test multiple plugins before settling on one.
Summary
So the next time you run your WordPress speed tests just be aware of how admin-ajax.php
slow responses might be affecting your site, both from a backend CPU utilization aspect and also third party plugins making repeated AJAX calls. It could be time to find a new alternative plugin. Another easy way to fix CPU loads due to the heartbeat API is to simply upgrade to a better web host or VPS.