If your server’s access log is full of POST /wp-admin/admin-ajax.php requests, or your hosting resources spike whenever editors have the dashboard open, the WordPress Heartbeat API is a likely cause. Heartbeat is useful, but it’s chatty by default. Here’s what it does and how to tune it.

What Heartbeat does

Heartbeat is a JavaScript timer in the browser that sends a request to admin-ajax.php (action heartbeat) every 15–60 seconds while a WordPress page is open. It powers:

  • Autosave and revisions while editing posts;
  • Post locking: “This post is being edited by another user”;
  • Session expiry warnings (the login pop-up when your session expires);
  • real-time notifications from plugins (WooCommerce, page builders, form plugins, and more).

Why it can hurt performance

Each heartbeat is a full WordPress PHP request: it loads WordPress and all active plugins. That’s not cached, and it’s not cheap. Examples:

  • Five editors with 3 tabs open each, every 15 seconds → 60 PHP requests per minute with no visitors at all.
  • An admin tab left open overnight keeps pinging.
  • On small servers, these requests take PHP-FPM workers away from real visitors, and push CPU up.

Check for yourself:

grep 'admin-ajax.php' /var/log/nginx/access.log | wc -l
grep 'admin-ajax.php' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head

Some admin-ajax traffic comes from plugins (front-end AJAX), not Heartbeat. The Query Monitor plugin, or browser DevTools, shows the action parameter. See Nginx access logs.

Increase the interval to 60 seconds (or up to 120) in a small site-specific plugin, or in the theme’s functions.php:

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

Autosave and post locking keep working, just less frequently.

Option 2: disable it where it isn’t needed

Heartbeat is mostly needed in the post editor. Disable it on the front end and the dashboard, and keep it in the editor:

add_action( 'init', function () {
    global $pagenow;
    if ( is_admin() && in_array( $pagenow, [ 'post.php', 'post-new.php' ], true ) ) {
        return; // keep in the editor
    }
    wp_deregister_script( 'heartbeat' );
}, 1 );

Test your site afterwards, because some plugins rely on Heartbeat in other screens.

Option 3: plugins

  • Heartbeat Control (by WP Rocket): set the frequency or disable it per location (dashboard, front end, editor), without code.
  • Many performance plugins (WP Rocket, Perfmatters, LiteSpeed Cache) include Heartbeat settings.

What breaks if you disable it completely

  • No autosave while editing (you can lose work).
  • No warning when two people edit the same post.
  • Session-expired pop-ups won’t appear (you lose unsaved work on submit).
  • Some plugin features (live notifications, WooCommerce admin updates, page builder autosave) stop working.

Usually it’s better to slow it down than to turn it off.

Other admin-ajax load: check plugins too

If admin-ajax traffic stays high after taming Heartbeat:

  • Find the action values (DevTools Network tab, or temporary logging).
  • Front-end AJAX from plugins (live search, cart fragments, counters, chat widgets) can be heavy. WooCommerce cart fragments is a classic. Disable it on pages that don’t need it, or use a plugin setting.
  • Use a page cache and object cache to make each PHP request cheaper. See Redis object cache.

Server-side tuning

Make sure PHP-FPM has enough workers for admin traffic plus visitors, and that a few slow admin requests can’t starve the site. See PHP-FPM tuning and WordPress performance tuning.

Quick reference

Goal How
Slow it down heartbeat_settings filter → interval 60
Keep only in editor deregister heartbeat outside post.php
No-code option Heartbeat Control plugin
Find admin-ajax sources access log + action parameter
Don’t disable it completely without testing

Related: WordPress cron jobs and WordPress VPS hosting.

  • WordPress
  • Performance
  • PHP