Posts

Fix For WordPress Heartbeat and Cron

Here is some Fixes to try if  admin-ajax and wp-cron are consuming too much resources on your hosting account

Lately I have been getting 504 gateway errors when I am editing pages in my blog here.
It turned out they are caused by hostgator limiting the resources on my hosting account due to excessive CPU . The support team sent me information that showed which files were causing the excessive CPU and Memory usage.

Fix WordPress from consuming too many hosting resources

Fix WordPress

 

upon examining the information I could clearly see that 2 files were being accessed excesively which were wp-cron and  and admin-ajax.php

the issue is relatively easy to fix but requires some editing to some files..

Hostgator support took care of the first problem for me which was to disable wp-cron from automatically firing and setup linux based cron for me

here is what the support team said about it:

By default, every time someone loads your site, the wp-cron.php file is run.
Most of the time, this isn't harmful. But if your wp-cron.php file is set to do some intense tasks, this can drive up resource usage.

Thus, you should convert the wp-cron.php task into a Linux cron job.
This is actually easier than you think. You simply need to have the Linux cron job utilize wget once an hour on the file via your URL.

So let us say your URL is http://example.com . Then the URL needed to call would be http://example.com/wp-cron.php?doing_wp_cron .

Since you don't want a million emails letting you know it run, you want to add 2>&1 at the end. Then we just want to call that via wget quietly.

Since we only want it running once per hour,

the coding for the cron job becomes:
0 * * * * /usr/bin/wget -q -O - http://example.com/wp-cron.php?doing_wp_cron 2>&1 Add that as a Linux cron job,

then add the following to your wp-config.php file:
define( 'DISABLE_WP_CRON', true );

 Have a Heart WordPress

The second issue is about admin-ajax.php being hammered. researching this I found out that wordpress heartbeat is a problem. I have a habit of having multiple tabs open with various admin pages left open. it seems that means wordpress heartbeat is in action for every page consuming cpu even when nothing is happening.. I found this article about it http://www.inmotionhosting.com/support/website/wordpress/heartbeat-ajax-php-usage

which I have recreated here so that I have a reference handy if this issue should arise on any of my other wordpress sites:

 
Wordpress Heartbeat

Slow down your WordPress Heartbeat

 

Introduced in WordPress 3.6 the WordPress Heartbeat API allows WordPress to communicate between the web-browser and the server. It allows for improved user session management, revision tracking, and auto saving.

The WordPress Heartbeat API uses /wp-admin/admin-ajax.php to run AJAX calls from the web-browser. Which in theory sounds awesome, as WordPress can keep track of what's going on in the dashboard.

However this can also start sending excessive requests to admin-ajax.php which can lead to high CPU usage. Anytime a web-browser is left open on a page using the Heartbeat API, this could potentially be an issue.

WordPress Heartbeat API in action

Something handled by the WordPress Heartbeat API is the main WordPress admin dashboard page itself. If all you did was login 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 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"

Now 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 notice that you are having an excessive amount of admin-ajax.php requests, the WordPress Heartbeat API can be disabled to prevent this type of activity from happening automatically.

By default WordPress uses the Heartbeat API to manage things such as post locking so only one admin can edit a post at once, it's also used for auto saving. Going forward the API could be used more and more by WordPress developers to handle certain tasks, so keep this in mind if you choose to disable 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 selectively 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 of your pages, and just slow down the rate at which requests happen by modifying the WordPress 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

Now it can get a bit tricky due to this JavaScript file being minimized, but essentially you want to find the 3 separate cases for request activity, 15 seconds, 30 seconds, and 60 seconds and increase the time of all of these.

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 hopefully understand what the WordPress Heartbeat API is, and how you can control it in the event it's causing too many requests to your admin-ajax.php script.