Understanding and Troubleshooting admin-ajax.php in WordPress

Last modified: September 11, 2025

Introduction

This guide will help you understand, diagnose, and resolve issues related to admin-ajax.php on your WordPress site. While admin-ajax.php is an essential WordPress file that enables many dynamic features, it can sometimes be the source of significant performance issues if not used efficiently by themes or plugins. The troubleshooting steps and solutions in this article are tailored specifically for the Pressable hosting platform and take into account our server environment and caching system, but much of the information below will also be relevant to other hosts.

When this guide won’t help

This guide specifically addresses admin-ajax.php performance issues. It won’t help with:

  • General server or hosting issues unrelated to AJAX requests
  • Database connection errors or corrupted databases
  • PHP errors unrelated to admin-ajax.php
  • Issues with static files (images, CSS, JavaScript files)
  • Problems that occur only on non-Pressable hosting

If your issue doesn’t match the symptoms described below, you may need different troubleshooting resources. Consider reaching out to the Pressable support team for their help locating relevant guides.

Part 1: The basics

What is the admin-ajax.php file?

The admin-ajax.php file is a core WordPress file that acts as a dedicated messenger between your website’s front-end (what visitors see) and back-end (the server). This communication process is called AJAX (Asynchronous JavaScript and XML), and it allows your website to send and receive small pieces of data in the background without needing to reload the entire page.

Think of it like a messenger service: instead of reloading a whole page just to update one small piece of information (like checking if you have new comments), WordPress can send a quick message through admin-ajax.php to get just that specific information and update only that part of the page.

Without this messenger, any small update would require a full page refresh, which is slow and can feel clunky. Instead, admin-ajax.php helps create smooth, modern web experiences such as:

  • Live comment updates without refreshing the page
  • Auto-saving drafts as you type
  • Dynamic shopping carts that update instantly when you change quantities
  • Interactive forms that show validation errors or success messages immediately
  • Filtered search results that update as you select filter criteria

Understanding the WordPress Heartbeat API

The WordPress Heartbeat API is a built-in feature that creates a regular connection, or “pulse,” between your browser and the WordPress server. It works like a regular heartbeat, sending small requests to the server every 15-60 seconds (depending on where you are in WordPress) to check for updates.

The Heartbeat API uses admin-ajax.php to handle these regular requests. It’s responsible for useful features like:

  • Auto-saving your posts while you write
  • Showing you when other users are editing the same post
  • Displaying real-time notifications in your admin dashboard
  • Keeping you logged in during long editing sessions
  • Running scheduled background tasks

While these features are helpful, the Heartbeat API is often the biggest source of admin-ajax.php requests on most websites.

Why high admin-ajax.php usage is a problem

Performance impact: Every request to admin-ajax.php requires a PHP worker (think of PHP workers as cashiers at a grocery store; they can only handle one customer or request at a time). If they’re all busy, new visitors have to wait in line.

Resource limits on Pressable: Your Pressable site has either 5 or 10 dedicated PHP workers, depending on your hosting plan, each with 512 MB of RAM. While your site can burst up to a max potential of 110 PHP workers depending on server pool availability, this full burst capacity is not guaranteed and is shared across the server pool. Consistently high admin-ajax.php usage can exhaust your available workers. Each request has a maximum of 120 seconds to complete before it times out. When workers are exhausted, this leads to:

  • Slow loading times for visitors
  • 502 Bad Gateway errors: “The proxy server received an invalid response from an upstream server”
  • 504 Gateway Timeout errors: “The server didn’t respond in time”
  • Poor performance in your WordPress admin area

The logged-out user problem: This is where a crucial distinction comes into play. While regular page views from logged-out visitors benefit from robust caching, admin-ajax.php requests from these same visitors typically bypass caching layers entirely. For example, if your contact form, search functionality, or “load more posts” buttons use AJAX calls, each click from a logged-out visitor creates an uncached request that hits your server directly.

The problem arises from scale: a single uncached request isn’t an issue, but on a high-traffic site, thousands of visitors can generate thousands of these individual uncached requests. This collective load can quickly overwhelm the available PHP workers and degrade performance for everyone, even though the pages themselves were served from cache.

Common symptoms of admin-ajax.php issues

You might be experiencing admin-ajax.php problems if you notice:

  • Slow or unresponsive WordPress admin dashboard (spinning wheels that take a long time to disappear)
  • General website slowness during specific actions (like submitting forms or using search filters)
  • 502 Bad Gateway errors (error pages saying “Bad Gateway: The proxy server received an invalid response from an upstream server”)
  • 504 Gateway Timeout errors (error pages with messages like “The server didn’t respond in time”)
  • Frequent timeouts when trying to save posts or access admin pages
  • High CPU usage notifications from Pressable about resource usage

Part 2: Advanced troubleshooting and solutions

How to identify the source of admin-ajax.php requests

Using browser developer tools:

Your web browser is the best tool for identifying which plugin, theme, or function is making all the requests.

  1. Open your website in Chrome or Firefox
  2. Right-click anywhere on the page and select “Inspect” or “Inspect Element”
  3. Click on the “Network” tab in the developer tools panel
  4. Refresh your page or perform the action that seems slow (you may need to refresh to start capturing activity)
  5. In the filter box, type “admin-ajax” to show only those requests
  6. Pay attention to the frequency and patterns:
    • Every 15-60 seconds at regular intervals: Likely the WordPress Heartbeat API
    • Random or irregular intervals: Likely a plugin checking for updates or notifications
    • Only on specific user actions: Likely a theme feature or form plugin
    • Continuous rapid-fire requests: Likely a misbehaving plugin that needs immediate attention
  7. Click on any admin-ajax.php request in the list
  8. Look for the “Payload,” “Params,” or “Request” tab (depending on your browser)
  9. Find the “action” parameter; this value often tells you which plugin or feature is making the request

For example, if you see action=heartbeat, that’s the WordPress Heartbeat API. If you see something like action=get_new_posts or action=woocommerce_update_cart, that points to a specific plugin or theme function.

[Advanced] Using WP-CLI:

Advanced users can use WP-CLI to check for scheduled tasks that might trigger AJAX requests:

wp cron event list

This command shows all scheduled tasks (cron jobs) on your site. Look for tasks that run very frequently (every few minutes) as these might be causing excessive admin-ajax.php requests.

This list is not exhaustive, but some types of cron events that may interact with admin-ajax.php include:

  • Plugin update checks –> Plugins sometimes trigger admin-ajax requests on a schedule to check for new versions.
  • Theme update checks –> Similar to plugins, some themes use admin-ajax for periodic update pings.
  • License validation –> Premium plugins or themes may schedule recurring admin-ajax calls to verify licenses.
  • Data sync –> Plugins that connect to external services (e.g., marketing, analytics, CRMs) may use admin-ajax to push or pull data.
  • Scheduled cleanup –>Security, SEO, or backup plugins may schedule admin-ajax tasks for cleanup routines like log rotation or cache purges.
  • Heartbeat API tasks –> Though primarily real-time, some heartbeat-based features also tie into cron-like schedules through admin-ajax.
  • Import/export routines –> Migration or import tools sometimes schedule chunked data processing via admin-ajax events.
  • Email sending –> Newsletter, form, or notification plugins may rely on scheduled admin-ajax calls to send queued emails.
  • Scheduled scans –>Malware, security, or broken-link scanners may trigger admin-ajax actions to process scans in timed chunks.
  • Database optimization –> Some plugins schedule admin-ajax events to optimize or repair database tables in the background.

For deeper analysis, you can use wp profile to monitor AJAX requests. Note that wp profile is not installed by default on Pressable and requires installing Composer first, which is beyond what our support team can assist with. This is only recommended for highly technical users comfortable with command-line tools and dependency management.

Solution 1: Managing the WordPress Heartbeat API

Often an effective way to reduce admin-ajax.php usage is to control when and how often the WordPress Heartbeat API runs. The goal is to balance its useful features with server performance.

Recommended approach: Instead of completely disabling the Heartbeat API (which can break some functionality), modify its behavior to be less resource-intensive.

Plugin suggestions:

  • Dynamic Front-End Heartbeat Control: Lets you adjust the frequency of heartbeat requests for front-end visitors without reducing Heartbeat utility in the WP Admin area.
  • Disable Everything: A simpler option for completely turning off the Heartbeat API if you don’t need its features. Please note that fully disabling built-in WordPress features without understanding the implications can result in unwanted issues. Only turn off options you explicitly don’t need, and consider testing this plugin on a staging clone before adding it to a live site.

Recommended initial settings for most sites:

Note that you may need to test variations to find the right settings for your specific site.

  • WordPress Dashboard: Modify Heartbeat to 60 seconds or higher (or disable if not needed)
  • Frontend: Disable Heartbeat entirely
  • Post Editor: Allow Heartbeat or modify to 60 seconds to reduce frequency while maintaining auto-save functionality

If you prefer not to use a plugin, this code snippet can be added to your theme’s functions.php file or via a code snippet plugin to achieve the settings above.

/**
 * Control WordPress Heartbeat API behavior.
 */
add_action( 'init', function() {
    // Disable Heartbeat on the frontend completely.
    if ( ! is_admin() ) {
        wp_deregister_script( 'heartbeat' );
    }
} );

add_filter( 'heartbeat_settings', function( $settings ) {
    global $pagenow;

    // Default to 60 seconds unless overridden.
    $settings['interval'] = 60;

    // WordPress Dashboard (index.php): disable or slow down further.
    if ( 'index.php' === $pagenow ) {
        // To fully disable Heartbeat on Dashboard, deregister the script:
        wp_deregister_script( 'heartbeat' );
        // Or if you prefer to keep it but slow it down more:
        // $settings['interval'] = 120;
    }

    // Post editor (post.php or post-new.php): keep Heartbeat but use a slower interval.
    if ( in_array( $pagenow, [ 'post.php', 'post-new.php' ], true ) ) {
        $settings['interval'] = 60; // still allows autosave but less frequent
    }

    return $settings;
} );

Expected results: After implementing these changes, you should see admin-ajax.php requests with action=heartbeat drop from every 15 seconds to every 60 seconds (or disappear entirely on the frontend) when monitoring in your browser’s Network tab.

Solution 2: Addressing issues from caching plugins

Understanding Pressable’s caching environment:

Pressable has multiple powerful caching layers built-in to make your site fast. Our system automatically adds object-cache.php and advanced-cache.php files in your WordPress installation. These files are symlinked (linked references to system files) and read-only; they cannot be modified or replaced.

The problem with third-party caching plugins:

Many caching plugins try to create their own versions of these files to handle caching functions. On Pressable, this causes conflicts because:

  • The plugins can’t overwrite our system files
  • They may generate errors trying to access files they can’t modify
  • Some plugins make frequent AJAX requests to try to manage caching, increasing admin-ajax.php usage
  • The plugins’ caching features won’t work properly, potentially making your site slower

Recommended action:

We recommend completely removing third-party page caching plugins; they are not necessary on our platform. If you’re using plugins like WP Rocket, W3 Total Cache, or WP Super Cache for other features:

  1. Disable any file-based caching features in the plugin settings
  2. Turn off object caching and database caching features
  3. Consider whether you need the plugin at all, since Pressable provides comprehensive caching automatically
  4. If you keep the plugin for other features (like minification or image optimization), ensure all caching-related functions are fully disabled

Expected results: After removing or properly configuring caching plugins, you should no longer see AJAX requests related to cache clearing or cache preloading in your browser’s Network tab. Error messages about being unable to write to cache files should also disappear.

Solution 3: Finding a problematic plugin or theme

If Heartbeat API management and caching plugin removal don’t solve your issue, a plugin or theme might be making excessive AJAX requests. We strongly recommend using a test clone for this testing. Never perform this testing on your live production site.

The standard deactivation process:

  1. Create a test clone of your site for troubleshooting
  2. Switch to a default theme like Twenty Twenty-Four to rule out theme-related issues
  3. Deactivate all plugins and check if the admin-ajax.php problems persist using your browser’s Network tab
  4. If the issue stops, reactivate your theme first and test again
  5. Then reactivate plugins one by one, testing your site’s performance after each activation
  6. When the problem returns, the last plugin you activated is likely the culprit

[Advanced] Using WP-CLI for faster testing:

If you’re comfortable with command-line tools, you can use WP-CLI to deactivate plugins more quickly:

List all installed plugins

wp plugin list

Deactivate all plugins at once (take note of which plugins are active and which are inactive before you run this, so you can return your site to the same state)

wp plugin deactivate --all

Deactivate a specific plugin

wp plugin deactivate [plugin-slug]

Reactivate specific plugins for testing

wp plugin activate [plugin-slug]

Expected results: When you find the problematic plugin or theme, the excessive admin-ajax.php requests should stop immediately upon deactivation. Make note of the specific action name from the Network tab before contacting the plugin/theme developer.

[Advanced/Developer] Code-level optimizations

For developers looking to optimize admin-ajax.php usage in custom code, here are some starter snippets that require customization for your specific use case:

Throttling AJAX requests:

// Throttle function to limit request frequency

let throttleTimer;

function throttledAjaxRequest(callback, delay = 1000) {

    clearTimeout(throttleTimer);

    throttleTimer = setTimeout(callback, delay);

}

// Usage example (customize for your needs)

jQuery(document).on('keyup', '.search-field', function() {

    throttledAjaxRequest(function() {

        // Your AJAX call here

    }, 500);

});

Batching multiple requests:

// Batch multiple data requests into one

let requestQueue = [];

let batchTimer;

function addToQueue(data) {

    requestQueue.push(data);

    clearTimeout(batchTimer);

    batchTimer = setTimeout(processBatch, 100);

}

function processBatch() {

    if (requestQueue.length === 0) return;

    jQuery.ajax({

        url: ajax_object.ajax_url,

        type: 'POST',

        data: {

            action: 'batch_process',

            requests: requestQueue,

            nonce: ajax_object.nonce

        }

    });

    requestQueue = [];

}

Using REST API instead of admin-ajax:

// Replace admin-ajax with REST API (better performance)

fetch('/wp-json/myplugin/v1/data', {

    method: 'POST',

    headers: {

        'Content-Type': 'application/json',

        'X-WP-Nonce': wpApiSettings.nonce

    },

    body: JSON.stringify({data: 'your-data'})

});

When to contact a developer

Some admin-ajax.php issues stem from inefficient or poorly coded plugins or custom themes that make unnecessary AJAX requests. If you’ve identified the source of the problem but can’t resolve it with the steps above, consider your options:

Contacting the plugin or theme developer:

  • Explain the specific issue you’re experiencing
  • Mention that you’re on a managed hosting platform with resource limits (the Pressable support team can help you locate specific details about server resources available for your plan if needed)
  • Provide a screenshot of the Network tab and the name of the AJAX action you identified
  • Ask if they have recommendations for reducing AJAX requests

Hiring a WordPress developer:

You may need professional help if:

  • The problematic code is in a custom theme or custom plugin
  • You’ve identified a specific plugin as the cause, but it’s essential to your site’s functionality
  • You’re seeing custom action names in the AJAX requests that don’t match any known plugins
  • You need to maintain certain functionality while reducing server load
  • The feature causing issues is custom-coded
  • The issue persists even after trying all the solutions above
  • You need help optimizing existing plugins
  • You want to implement custom solutions to reduce admin-ajax.php usage
  • You need to balance essential functionality with performance requirements

Consider reaching out to a few of our partner agencies for a quote or more information.

Preventing future admin-ajax.php issues

Best practices for maintaining optimal performance:

  1. Limit admin dashboard access: Reduce the number of users who regularly access the WordPress admin area. Each logged-in user generates Heartbeat requests.
  2. Choose plugins wisely: Before installing a plugin, research whether it’s known for performance issues. Avoid plugins that:
    –> Promise “real-time” features for all visitors
    –> Add live chat or social media feeds
    –> Continuously check for external updates
  3. Regular performance audits: Periodically check your site’s admin-ajax.php usage using the browser developer tools method described above, especially after adding new plugins or features.
  4. Use built-in WordPress features: When possible, use WordPress core features instead of plugins that might add unnecessary AJAX requests.
  5. Consider static alternatives: For features like contact forms on low-traffic pages, consider whether a simple email link might work just as well as a dynamic form plugin.
  6. Monitor after updates: Plugin and theme updates can introduce new AJAX functionality. Check your site’s performance after major updates.

Expected long-term results: Following these preventive measures should help maintain consistent site performance with minimal admin-ajax.php related issues. Sites following these practices typically see significantly fewer AJAX requests compared to unoptimized sites.