SYSTEMS OPERATIONAL
WordPress

WordPress Heartbeat API Eating CPU? Here's How to Fix It

Getwebup 5 min read

If your hosting dashboard shows a WordPress site pegging the CPU even when nobody's actively editing anything, open your server's access log and look for repeated POST requests to /wp-admin/admin-ajax.php. If they're firing every 15 to 60 seconds from open browser tabs, you've found your culprit: the WordPress Heartbeat API.

Symptom: Steady CPU Load With No Obvious Traffic Spike

This one's easy to misdiagnose because it doesn't look like a traffic problem. Your visitor numbers are normal, there's no DDoS, no crawler storm - but your VPS load average sits stubbornly high, or on shared hosting you keep hitting a CloudLinux LVE resource limit. Check your access log:

tail -f /home/username/access-logs/yourdomain.com | grep admin-ajax.php

If you see a wall of POST requests to admin-ajax.php, cross-reference the timing. Heartbeat fires roughly every 15 seconds on post-edit screens and every 60 seconds on the wp-admin dashboard by default. A handful of staff who leave their WordPress admin tab open all day is enough to keep a small VPS busy around the clock.

Cause: What the Heartbeat API Actually Does

Heartbeat isn't a bug - it's a real feature WordPress core introduced to support things like:

  • Auto-save and post-lock warnings ("this post is being edited by another user")
  • Live session expiry checks and login-timeout warnings
  • Plugin dashboards that need near-real-time updates (some page builders, some security plugins)

The problem is that every one of those AJAX calls is a full WordPress bootstrap: PHP loads, plugins init, and in a lot of cases a database query runs. Multiply that by every open admin tab, every 15-60 seconds, across every logged-in editor, and you get a steady background load that never shows up as a "traffic spike" but absolutely shows up in your hosting bill or resource warnings.

It gets worse on WooCommerce and membership sites, where some front-end pages also load Heartbeat for cart or session syncing - so it's not always confined to /wp-admin/.

Fix: Throttle It, Don't Just Kill It

Completely disabling Heartbeat is tempting, but it breaks post-locking (two editors can silently overwrite each other's work) and session-expiry warnings. The safer move is to slow it down and limit where it runs.

1. Confirm the diagnosis first

Before changing anything, install Query Monitor or check your browser's Network tab on wp-admin with a filter for admin-ajax.php. Confirm the action=heartbeat parameter is actually what's firing repeatedly - some plugins fake similar polling patterns and you don't want to "fix" the wrong thing.

2. Throttle the interval with a plugin

The simplest fix for most site owners is the free Heartbeat Control plugin. It lets you set separate behavior for the dashboard, post editor, and front end without editing code:

  • Dashboard: slow to 60-120 seconds (or disable entirely if nobody needs live updates there)
  • Post editor: keep it enabled but slow to 30-60 seconds so autosave/post-lock still work
  • Front end: disable unless you're running WooCommerce cart features that depend on it

3. Or throttle it in code (no plugin)

If you'd rather not add another plugin, drop this in your theme's functions.php or a site-specific plugin:

add_filter( 'heartbeat_settings', function ( $settings ) {
    $settings['interval'] = 60; // seconds, minimum enforced is 15
    return $settings;
} );

add_action( 'init', function () {
    if ( ! is_admin() ) {
        wp_deregister_script( 'heartbeat' );
    }
}, 1 );

That keeps Heartbeat alive in wp-admin (so post-locking still works) but strips it from front-end pages entirely - usually the biggest win on WooCommerce or membership sites.

4. Check for plugin-specific Heartbeat abuse

Some page builders and security plugins hardcode their own aggressive polling on top of core Heartbeat. If CPU stays high after throttling core Heartbeat, deactivate plugins one at a time and re-check admin-ajax.php traffic - Elementor, Divi, and a few live-stats security plugins are repeat offenders here.

5. Verify with server-side monitoring

On a VPS, watch load before and after with:

top -o %CPU

On cPanel/shared hosting, check WHM's Resource Usage or your CloudLinux LVE stats page for the account. You should see PHP process counts drop noticeably within a few minutes of the fix taking effect - Heartbeat calls tend to be short but frequent, so the change shows up fast.

Prevention: Keep Heartbeat From Creeping Back Up

  • Audit new plugins before activating them - check if they add their own AJAX polling, not just Heartbeat hooks.
  • Set a site policy for idle admin tabs - if your team routinely leaves 5-10 wp-admin tabs open overnight, that's constant background load for no reason. A simple "close the tab when you're done" habit saves real CPU.
  • Re-check after major WordPress or plugin updates - Heartbeat behavior and defaults have shifted across WP versions, and plugin updates can silently re-enable front-end polling you'd previously turned off.
  • Pair this with object caching - if you're on a Getwebup VPS, adding Redis object cache reduces the DB load each Heartbeat tick causes, even if you can't fully control how often it fires.

None of this is a one-time fix-and-forget. Heartbeat settings live in code or plugin config, and both can get reset by updates - so it's worth a quick recheck of admin-ajax.php traffic whenever CPU usage creeps up again for no clear reason.

Frequently asked questions

Will disabling Heartbeat break WordPress?

Not entirely, but it removes features that depend on it: auto-save conflict warnings, post-locking between editors, and session-expiry alerts. Throttling the interval instead of fully disabling it keeps those features while cutting the request volume drastically.

How do I know if Heartbeat is really the cause of high CPU, not something else?

Tail your access log filtered to admin-ajax.php and watch the timing - repeated requests every 15-60 seconds from a handful of IPs (your logged-in editors) is the signature. If the requests are irregular or coming from many different IPs, you're more likely looking at bot traffic or a different plugin issue.

Does Heartbeat run on the front end of my site, not just wp-admin?

By default it's mostly confined to wp-admin, but some plugins - especially WooCommerce cart/session features and certain page builders - explicitly enable it on front-end pages too. Check your Network tab on a logged-out front-end page to confirm before assuming it's admin-only.

What's the minimum Heartbeat interval WordPress allows?

15 seconds is the floor - WordPress core won't let you set it lower even via the heartbeat_settings filter. You can go higher (60, 120 seconds, or effectively off by deregistering the script) but not below 15.

Is this different from the general 'VPS high CPU' troubleshooting steps?

Yes - general high-CPU diagnosis covers server-wide causes like PHP-FPM pool sizing, MySQL query load, or traffic spikes. Heartbeat is a WordPress-specific, admin-side cause that produces steady background load even with normal visitor traffic, which is why it's easy to miss if you're only checking server-level metrics.

#wordpress #heartbeat-api #admin-ajax #high-cpu #performance #cpanel

Keep reading

Chat with Support