We often receive letters to the editorial office asking us to deal with the load on the WordPress site, and in many cases, this is due to the admin-ajax.php file. In this article, we will tell you what this file is responsible for and how to deal with its load on the server.
AJAX requests and admin-ajax.php
In WordPress, this approach is used in many places: working with media files, automatically saving posts, managing revisions, working with custom fields, working with widgets, and much more. And in order not to reinvent the wheel every time, the admin-ajax.php file in WordPress provides a convenient API for working with AJAX requests.
In this article, we will not consider the API itself, but it is worth noting that despite the presence of the word “admin” in the file name, requests from the front of the site can also pass through it, including anonymous requests from WordPress themes and plugins. Unfortunately, many sources mistakenly advise disabling this file, or blocking it with a password – this is not worth doing.
A large number of requests to admin-ajax.php
As we already mentioned, the admin-ajax.php file is called when automatically saving posts and also to update locks so that two users cannot edit the same post at the same time. This implements an API in WordPress called Heartbeat which is built around admin-ajax.php.
When editing a post, Heartbeat sends a request to admin-ajax.php every 15 seconds (or every 60 seconds if the browser tab is not active). Therefore, if you see a large number of requests to admin-ajax.php in your web server logs, it is worth analyzing them.
- What IP addresses are these requests coming from?
- How often do they come?
- How long does one such request take on average?
- What is the content of the request?
So, if these requests come from your IP address, or from the IP addresses of editors on your site, if their frequency is about 15-60 seconds if each such request takes no more than 0.5 seconds, and the content of the requests does not contain anything unusual, then everything is in okay – the admin-ajax.php file is not a source of load on your server, regardless of the “large” number of requests. And if your hosting provider assures you otherwise, then we advise you to think about his competence and about a possible move.
When admin-ajax.php is really a problem
Let’s look at a few options when admin-ajax.php really becomes a source of high load on your server, and how to deal with this load.
Requests to admin-ajax.php take more than 1 second
On average, requests to admin-ajax.php can take around 300ms. If on your site these requests are completed in more than one second, then you need to figure it out. Use profiling tools to understand exactly what the process is doing all this time. You will most likely find a slow function in your theme or plugin that has nothing to do with AJAX requests.
If you do not own profiling tools, or you do not have time to understand someone else’s code, then try disabling all plugins and activating the default WordPress theme. Then activate the plugins in order to see which one is causing the slow requests to admin-ajax.php.
It also happens that requests to admin-ajax.php become slow not because of specific plugins or themes, but because of a suboptimal MySQL server configuration. This happens quite rarely, and in this case, you should focus on optimizing the database server.
Suspicious request content
The admin-ajax.php (and admin-post.php) file is often chosen by attackers to exploit a known vulnerability in a plugin. An example is a recent incident with the popular FancyBox plugin, where admin-ajax.php (or admin-post.php) served as the entry point.
These files are chosen for a reason because each of them executes an event admin_init even for anonymous HTTP requests. Many plugins and theme developers mistakenly believe that once the event admin_initis fired, the user is logged in and has administrator rights. This is not true. We repeat – the event admin_initis executed even for anonymous HTTP requests.
So, in the case of the FancyBox for WordPress plugin vulnerability, this is roughly what “suspicious request content” looks like:
18.104.22.168 – – [04/Feb/2015:00:25:09 -0500] "POST /wp-admin/admin-ajax.php?page=fancybox-for-wordpress HTTP/1.1" 403 4207 INPUTBODY:action=update&mfbfw%5Bext...
If you find such a request, you need to understand what specific plugin or theme it is targeting, what exactly it is trying to do, whether it succeeded. In such cases, we recommend contacting WordPress security experts.
Unrecognizable IP addresses
This point is closely related to the previous one. If you see requests to admin-ajax.php from unrecognizable IP addresses, then you need to analyze these requests and understand what exactly the attacker is trying to do. IP addresses can be banned, for example by a pattern using fail2ban.
Too frequent requests
As we already mentioned, in the active tab, when editing a post, WordPress makes an AJAX request every 15 seconds, i.e. to achieve 1 request per second on the server, you need 15 editors with an open tab. If you are the only editor on your site, and requests to admin-ajax.php from your IP address are more than 1 per second (we have seen 20/s), then you should deal with this.
The most common reason for this behavior is a theme or plugin, so you should deactivate and enable them in order to find the source. Also worth mentioning here is the Heartbeat Control plugin, which allows you to change the default Heartbeat configuration in WordPress, but keep in mind that by disabling Heartbeat you are temporarily hiding the problem rather than fixing it.
In this article, we have considered several reasons why a high load on the hosting site can occur through the admin-ajax.php file, but it is possible that there may be others.
In the case of any “extra” load on the server, we recommend that you always check the facts, profiling tools are your best friends. The results are sometimes surprising when, for example, some of the very popular WordPress plugins turn out to be the slowest.