
The WordPress Heartbeat API is one of those under-the-hood features many site owners are unaware of, yet it plays a critical role in how WordPress operates—especially in the admin area. However, it can also affect your website’s performance if not managed correctly.
In this post, I will break down everything you need to know about the WordPress Heartbeat API: what it does, why it matters, how to optimize it, and even how to disable it when it’s not needed.
Table of Contents
WordPress Heartbeat API Tutorial for Beginners
The Heartbeat API is a simple server polling system built into WordPress that allows near real-time updates between the client (browser) and server. It’s extremely useful for enabling features like post autosave, session timeout alerts, and user activity monitoring.
History of the Heartbeat API
The WordPress Heartbeat API was introduced in WordPress 3.6 (released in August 2013) as part of an effort to make WordPress more dynamic and responsive in real time. The main motivation was to enhance the user experience during post editing, particularly for features like:
- Post Locking: Avoiding conflicts when multiple users edit the same post.
- Auto-save Improvements: Ensuring changes are saved without losing progress.
- Session Expiration Notifications: Letting users know when their session is about to expire.
Since its release, the Heartbeat API has also been adopted by plugin and theme developers to create real-time features in both admin and frontend interfaces.
🧠 What Does the Heartbeat API Do?
- Auto-Saving Posts
It automatically saves your content while you’re editing, preventing data loss. - Post Locking
Shows a warning if another user is editing the same post, avoiding conflicts. - Session Expiration Warning
Notifies users if their login session is about to expire. - Plugin & Theme Communication
Some plugins (like page builders, SEO tools) use it for background syncing. While some may utilize it for live notifications, analytics, or real-time updates. - Dashboard Widgets:
Some plugins use it to fetch dynamic data.
Why Should You Optimize or Disable Heartbeat?
While Heartbeat is useful, it can cause performance issues on high-traffic or shared hosting environments due to:
- Excessive admin-ajax.php requests
- Increased server CPU usage
- Resource-heavy plugins misusing it
If you’re not using real-time updates or post locking, you can safely disable or limit it.
How to Detect Heartbeat on the Frontend?
// Detect if Heartbeat is enqueued on the frontend
add_action('wp_enqueue_scripts', 'detect_frontend_heartbeat', 20);
function detect_frontend_heartbeat() {
if (wp_script_is('heartbeat', 'enqueued')) {
error_log('Heartbeat is being used on the FRONTEND.');
} else {
error_log('No Heartbeat on the frontend.');
}
}Code language: JavaScript (javascript)
How to Detect Heartbeat on the Backend (Admin Area)
// Detect if Heartbeat is enqueued in the admin area
add_action('admin_enqueue_scripts', 'detect_backend_heartbeat', 20);
function detect_backend_heartbeat() {
if (wp_script_is('heartbeat', 'enqueued')) {
error_log('Heartbeat is being used in the BACKEND.');
} else {
error_log('No Heartbeat in the backend.');
}
}Code language: JavaScript (javascript)
How it works:
- This checks if the
heartbeatscript is enqueued. - The results will appear in your debug log file if you have logging enabled (
wp-content/debug.log). - You can also replace
error_log()with your custom logic, like showing admin notices or toggling features.
Make sure your wp-config.php has:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);Code language: JavaScript (javascript)
How to Disable WordPress Heartbeat API?
You can completely disable it using a simple function in your theme’s functions.php:
add_filter( 'heartbeat_send', '__return_false' );Code language: JavaScript (javascript)
Or more selectively:
add_action( 'init', 'disable_heartbeat_everywhere' );
function disable_heartbeat_everywhere() {
wp_deregister_script('heartbeat');
}Code language: JavaScript (javascript)
How to Disable Heartbeat on Frontend Only
Add this to your functions.php:
add_action( 'init', 'disable_heartbeat_frontend', 1 );
function disable_heartbeat_frontend() {
if ( ! is_admin() ) {
wp_deregister_script( 'heartbeat' );
}
}Code language: JavaScript (javascript)
Disable Heartbeat on the Dashboard Only
add_action( 'admin_enqueue_scripts', 'disable_dashboard_heartbeat' );
function disable_dashboard_heartbeat() {
global $pagenow;
if ( 'index.php' === $pagenow ) {
wp_deregister_script( 'heartbeat' );
}
}Code language: PHP (php)
How to Limit Heartbeat Frequency?
If you don’t want to disable it, you can control how often it runs.
add_filter( 'heartbeat_send_interval', 'custom_heartbeat_interval' );
function custom_heartbeat_interval( $interval ) {
return 60; // in seconds
}Code language: PHP (php)
Default is 15 seconds on the post editor screen.
Use a Plugin (Non-Technical Option)
If you prefer a plugin to manage this easily:
- ✅ Heartbeat Control by WP Rocket (Free)
https://wordpress.org/plugins/heartbeat-control/
It allows you to:
- Disable heartbeat on frontend, backend, or post edit pages.
- Adjust frequency (15s, 30s, 60s).
- No coding required.
How WordPress Heartbeat API Works – With Real-Life Examples
When a page loads, WordPress initiates the Heartbeat script on the frontend or backend. It creates a time interval (known as a “tick”) that runs every 15 to 120 seconds. Here’s what happens:
- The client-side JavaScript triggers a
heartbeat-sendevent and includes optional custom data. - This data is sent to
admin-ajax.phpvia AJAX. - The server processes the data using the
heartbeat_receivedfilter. - A response is returned in JSON format.
- The client receives this response and triggers a
heartbeat-tickevent.
Example: Using the API
To use the Heartbeat API for custom functionality, you need to:
- Send custom data from JavaScript.
- Handle that data server-side in PHP.
- Process the returned data back in JavaScript.
Sending Data to the Server
jQuery( document ).on( 'heartbeat-send', function ( event, data ) {
// Add additional data to Heartbeat data.
data.myplugin_customfield = 'some_data';
});Code language: JavaScript (javascript)
Receiving and Responding on the Server
function myplugin_receive_heartbeat( array $response, array $data ) {
// If we didn't receive our data, don't send any back.
if ( empty( $data['myplugin_customfield'] ) ) {
return $response;
}
// Hash the received data and return it.
$received_data = $data['myplugin_customfield'];
$response['myplugin_customfield_hashed'] = sha1( $received_data );
return $response;
}
add_filter( 'heartbeat_received', 'myplugin_receive_heartbeat', 10, 2 );Code language: PHP (php)
Processing the Response on the Frontend
jQuery( document ).on( 'heartbeat-tick', function ( event, data ) {
// Use the returned hashed value.
if ( ! data.myplugin_customfield_hashed ) {
return;
}
alert( 'The hash is ' + data.myplugin_customfield_hashed );
});Code language: JavaScript (javascript)
Not every use case will require all three steps. For example, if you just want to receive updated information from the server, you can skip the
heartbeat-sendevent.
Real-Life Example 1: Display Live Order Status in Admin Panel
The Problem
Let’s say you run an eCommerce site using WooCommerce. As an admin, you want to see live order updates on your custom dashboard without needing to refresh the page every few seconds.
For example, if a customer places a new order, you want the admin screen to reflect that in real time.
The Solution Using WordPress Heartbeat API
You can use the Heartbeat API to check for new orders every 30 seconds and update the dashboard widget dynamically.
Step 1: Send the request to check for new orders
jQuery(document).on('heartbeat-send', function(event, data) {
data.check_new_orders = true;
});Code language: JavaScript (javascript)
Step 2: Handle the request in PHP and send back new order count
add_filter('heartbeat_received', 'check_for_new_orders', 10, 2);
function check_for_new_orders($response, $data) {
if (isset($data['check_new_orders']) && current_user_can('manage_woocommerce')) {
$new_orders = wc_orders_count('processing');
$response['new_order_count'] = $new_orders;
}
return $response;
}Code language: PHP (php)
Step 3: Handle the response on the frontend
jQuery(document).on('heartbeat-tick', function(event, data) {
if (data.new_order_count !== undefined) {
jQuery('#new-order-count').text(data.new_order_count);
}
});Code language: JavaScript (javascript)
Step 4: Add the HTML to show the count
<div id="new-order-count">0</div>Code language: HTML, XML (xml)
This way, your dashboard can reflect live order counts using the Heartbeat API without needing constant manual refreshes.
Real-Life Example 2: Show Live Word Count While Writing a Post
The Problem
While writing a long blog post in the WordPress editor, you want to show the total word count of the post updating in real time, without refreshing or re-saving the post.
The Solution Using WordPress Heartbeat API
You can create a live word count feature using the Heartbeat API.
Step 1: Send the content from the editor to the server
jQuery(document).on('heartbeat-send', function(event, data) {
const content = tinymce.activeEditor.getContent({ format: 'text' });
data.live_word_count = content;
});Code language: JavaScript (javascript)
Step 2: Receive content on the server and calculate word count
add_filter('heartbeat_received', 'calculate_live_word_count', 10, 2);
function calculate_live_word_count($response, $data) {
if (!empty($data['live_word_count'])) {
$content = strip_tags($data['live_word_count']);
$word_count = str_word_count($content);
$response['live_word_count_result'] = $word_count;
}
return $response;
}Code language: PHP (php)
Step 3: Show live word count in real-time
jQuery(document).on('heartbeat-tick', function(event, data) {
if (data.live_word_count_result !== undefined) {
jQuery('#live-word-count').text(data.live_word_count_result + ' words');
}
});Code language: JavaScript (javascript)
Step 4: Add HTML Element to Post Editor Page
You can manually inject the following HTML in your custom admin UI or extend the post editor using JavaScript:
<div id="live-word-count">0 words</div>Code language: HTML, XML (xml)
This will display a live word count while writing content.
FAQs About WordPress Heartbeat API
-
What is the WordPress Heartbeat API?
-
Can I disable the Heartbeat API completely?
-
Will disabling Heartbeat affect autosave?
-
How often does Heartbeat send data?
-
Is Heartbeat API resource-heavy?
-
How can I reduce Heartbeat API load?
-
Is Heartbeat used on the frontend?
-
Can I customize the data sent through Heartbeat?
-
What happens if I disable Heartbeat only on the dashboard?
-
Which plugin is best for managing Heartbeat?
Disclaimer
Make sure you test any Heartbeat API configuration on a staging site before deploying it live. Disabling the API in the wrong area could break autosave, post locking, or other plugin features.
Conclusion
The WordPress Heartbeat API is a powerful tool for real-time syncing, but it can cause performance issues if misused or left unchecked. By understanding where and how it operates, you can make informed decisions to disable or optimize it for better performance.
Use the code samples or plugin suggestions above to fine-tune your Heartbeat API usage — just make sure to test thoroughly first!
If you’re just starting your WordPress journey, check out my full collection of beginner-friendly tutorials that make learning easy and fun.


