Navigation:

The WordPress Heartbeat API allows WordPress to communicate between the web-browser and the server. It also improves session management, revision tracking, and auto saving. The WordPress Heartbeat API uses /wp-admin/admin-ajax.php, which allows WordPress to keep track of what's going on in the dashboard.

Unfortunately, this can also cause excessive requests to admin-ajax.php, leading to high CPU usage. Whenever a web-browser is left open on a page using the Heartbeat API, this could potentially be an issue.

WordPress Heartbeat API in action

The main WordPress admin dashboard page itself is handled by the WordPress Heartbeat API is . If you just logged in to WordPress, and then minimized that window and started working on something else, you'd see requests for admin-ajax.php in your site's access logs.

At [00:29:30] I logged into the dashboard, and you can see the initial GET /wp-admin/index.php request.

Then at [00:30:31] the WordPress Heartbeat API sends a POST /wp-admin/admin-ajax.php Heartbeat request.

With the WordPress dashboard in focus, a Heartbeat request should be spaced to the max of 60 seconds that the API allows for. If the dashboard is out of focus, the Heartbeat requests space out to 120 seconds between them.

00:29:30 "GET /wp-admin/index.php "http://example.com/wp-admin/index.php"
00:30:31 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:32:03 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:33:03 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:34:03 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:35:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:36:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:37:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:38:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:39:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:40:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:42:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:44:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:46:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:47:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:48:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:49:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:50:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:51:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:53:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:55:08 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:57:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
00:59:04 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
01:01:05 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"
01:03:05 "POST /wp-admin/admin-ajax.php "http://example.com/wp-admin/index.php"

Each of those POST requests had a corresponding PHP script execution on the server using CPU time:

php-cgi 0.26 secs Wed Feb 19 00:29
php-cgi 0.26 secs Wed Feb 19 00:30
php-cgi 0.23 secs Wed Feb 19 00:32
php-cgi 0.20 secs Wed Feb 19 00:33
php-cgi 0.22 secs Wed Feb 19 00:34
php-cgi 0.24 secs Wed Feb 19 00:35
php-cgi 0.20 secs Wed Feb 19 00:36
php-cgi 0.23 secs Wed Feb 19 00:37
php-cgi 0.23 secs Wed Feb 19 00:38
php-cgi 0.26 secs Wed Feb 19 00:39
php-cgi 0.22 secs Wed Feb 19 00:40
php-cgi 0.23 secs Wed Feb 19 00:42
php-cgi 0.22 secs Wed Feb 19 00:44
php-cgi 0.23 secs Wed Feb 19 00:46
php-cgi 0.25 secs Wed Feb 19 00:47
php-cgi 0.27 secs Wed Feb 19 00:48
php-cgi 0.23 secs Wed Feb 19 00:49
php-cgi 0.22 secs Wed Feb 19 00:50
php-cgi 0.21 secs Wed Feb 19 00:51
php-cgi 0.21 secs Wed Feb 19 00:53
php-cgi 0.21 secs Wed Feb 19 00:55
php-cgi 0.24 secs Wed Feb 19 00:57
php-cgi 0.25 secs Wed Feb 19 00:59
php-cgi 0.22 secs Wed Feb 19 01:01
php-cgi 0.23 secs Wed Feb 19 01:03

Having our dashboard open for over a half hour, generated 25 PHP script executions. With a total usage of 5.77 CPU seconds. Not terrible, but not great either, since we used up CPU essentially checking for nothing to happen.

Disable WordPress Heartbeat API

If you see a lot of admin-ajax.php requests, you can disable the WordPress Heartbeat API to automatically stop them.

WordPress uses the Heartbeat API for features such as auto saving, or warning users when their login expires. Keep in mind, disabling the Heartbeat API can affect other future features that use it.

Navigation:


Locate your functions.php script

To modify the behavior of the Heartbeat API, locate your WordPress theme's functions.php script.

I'm using the default twentyfourteen theme, so my path looks like:

/home/userna5/public_html/wp-content/themes/twentyfourteen/functions.php

Make a copy of this file, something like functions.php-BAK for safe keeping.

Disable WordPress Heartbeat everywhere

Towards the top of the functions.php file, add the highlighted code to disable the Heartbeat everywhere:

 * @since Twenty Fourteen 1.0
 */

add_action( 'init', 'stop_heartbeat', 1 );

function stop_heartbeat() {
        wp_deregister_script('heartbeat');
}

/**
 * Set up the content width value based on the theme's design.

Disable WordPress Heartbeat just on Dashboard page

To disable the Heartbeat API on certain pages, you can use the global WordPress $pagenow variable to tell what page a user is on. Along with an if statement to tell WordPress if the Heartbeat API should be used.

You can check if the $pagenow variable is a specific page, and if so turn off the Heartbeat:

add_action( 'init', 'stop_heartbeat', 1 );

function stop_heartbeat() {
        global $pagenow;

        if ( $pagenow == 'index.php'  )
        wp_deregister_script('heartbeat');
}

Disable Heartbeat everywhere except post.php and post-new.php

You can also check if the $pagenow variable is not set to specific pages that you would still like the Heartbeat to happen on, such as post.php or post-new.php, and then turn off the Heartbeat on every page but those.

add_action( 'init', 'stop_heartbeat', 1 );

function stop_heartbeat() {
        global $pagenow;

        if ( $pagenow != 'post.php' && $pagenow != 'post-new.php' )
        wp_deregister_script('heartbeat');
}

Then just save your functions.php script, after choosing where you'd like the Heartbeat to be disabled.

Delay WordPress Heartbeat requests

You can also leave the WordPress Heartbeat API enabled for all pages, and slow down the rate of the requests by modifying the WP Heartbeat JavaScript file.

This can be a great method to use if you'd still like to have all the functionality that the Heartbeat API provides by default, but still reduce the overall usage it requires to run.

Change the rate of the default Heartbeat requests

First make a backup copy of this file:

/home/userna5/public_html/wp-includes/js/heartbeat.min.js

Find the 3 separate instances for request activity, 15 seconds, 30 seconds, and 60 seconds, and increase the time intervals.

In all the examples below, the ...'s indicate that there is other code you don't need to edit in-between the parts you do need to edit.

15 Second requests

To extend the default behavior of having a Heartbeat request every 15 seconds, you would look for this code:

B.mainInterval<15?B.mainInterval=15:...case 15:

Change it to something like 120 to extend Hearbeat requests out to 2 minutes by default:

B.mainInterval<120?B.mainInterval=120:...case 120:

30 Second requests

To extend the behavior of having a Heartbeat request every 30 seconds, you would look for this code:

case 30:...30,b=1>b||b>30?30:

Change it to something like 300 to extend Hearbeat requests out to 5 minutes:

case 300:...300,b=1>b||b>300?300:

60 Second requests

To extend the behavior of having a Heartbeat request every 60 seconds, you would look for this code:

B.mainInterval>60&&(B.mainInterval=60))...case 60:...mainInterval:60

Change it to something like 600 to extend Hearbeat requests out to 10 minutes:

B.mainInterval>600&&(B.mainInterval=600))...case 600:...mainInterval:600

You should now understand what the WordPress Heartbeat API is, and reduce requests to your admin-ajax.php script.

Did you find this article helpful?

We value your feedback!

Why was this article not helpful? (Check all that apply)
The article is too difficult or too technical to follow.
There is a step or detail missing from the instructions.
The information is incorrect or out-of-date.
It does not resolve the question/problem I have.
How did you find this article?
Please tell us how we can improve this article:
Email Address
Name

new! - Enter your name and email address above and we will post your feedback in the comments on this page!

Did you find this article helpful?

Comments

n/a Points
2014-12-06 6:19 pm

Unfortionaly it didn't work from me

/wp-admin/admin-ajax.php

still loading every single request on my site this really silly I don't if it reason to heavy load on my site

n/a Points
2014-12-06 6:36 pm

OK I figuar it out /wp-admin/admin-ajax.php file was loaded by wp slim stats plugin not due to  WordPress Heartbeat

The code work  perfect and /admin-ajax.php not loaded again

 

n/a Points
2017-03-29 5:59 pm

Thank for so much for sharing this valuable information with precise details and the solution aswell.

Keep posting.

Cheers :)

n/a Points
2017-03-29 6:00 pm
Thank you so much for sharing such a valuable information(with stats) and solution.
I am running a News website where multiple authors (~ 15 users) keep writing articles during office hours (~ 7 hours). Though I am having a hostgator's managed WP hosting, I was running into big problem due to the heartbeat...because disabling it totally was also disabling the Autosaving or posts.
But now I got this very useful solution of enabling heartbeat only where it is required.
Thanks again. :)

Post a Comment

Name:
Email Address:
Phone Number:
Comment:
Submit

Please note: Your name and comment will be displayed, but we will not show your email address.

Related Questions

Here are a few questions related to this article that our customers have asked:
Ooops! It looks like there are no questions about this page.
Would you like to ask a question about this page? If so, click the button below!
Need More Help?

Help Center Search

Current Customers

Email: support@WebHostingHub.com Ticket: Submit a Support Ticket
Call: 757-416-6627 Chat: Click To Chat Now

Ask the Community

Get help with your questions from our community of like-minded hosting users and Web Hosting Hub Staff.

Not a Customer?

Get web hosting from a company that is here to help.
}