Key points:

  • admin-ajax.php bottlenecks because every request loads WordPress, hides plugin origins, and strains under high-frequency calls.
  • Trace problems with Network tab, Query Monitor’s Caller column, and error logs to pinpoint the exact action and cause.
  • Optimize at the action level with caching, pagination, throttling, REST migration, and nonce validation, then validate gains with before/after metrics.

When admin-ajax.php is consuming massive resources on your WordPress site, it’s frustrating. The deeper you dig, the more it seems like core WordPress code is at fault, but the real issue can be more elusive.

Imagine a busy restaurant kitchen with a single door through which all the waiters pass to reach the seating area. When service slows down, focusing on the door doesn’t tell you which waiter is causing the holdup. Similarly, admin-ajax.php processes requests for many different features, so when performance suffers, it’s not always clear which request or plugin is the problem.

Join us as we break down how admin-ajax.php works, common performance issues it causes, and how to troubleshoot and optimize it effectively for your WordPress site.

Why admin-ajax.php becomes your WordPress bottleneck

admin-ajax.php handles asynchronous requests in WordPress, but it can quickly become a performance bottleneck if not optimized.

Each AJAX call triggers the entire WordPress environment – core files, active plugins, and the theme. This means that PHP must execute heavy bootstrap logic for every request, which can be resource-intensive. On top of that, database queries are often run repeatedly without built-in caching, causing unnecessary load on the server.

High-frequency requests, such as polling or auto-refreshing, amplify the problem by increasing the strain on the server.

Additionally, while AJAX requests are asynchronous from the browser’s perspective, admin-ajax.php handles them sequentially on the server, which can create bottlenecks during high traffic periods.

This can lead to delays, especially when multiple requests are made simultaneously. As a result, poorly optimized AJAX calls can slow down your site and overwhelm your server.

Find exactly which plugin hammers admin-ajax.php

When admin-ajax.php is causing performance issues, pinpointing the exact plugin responsible can be tricky. Here’s a step-by-step guide to help you identify the culprit:

  1. Open your browser’s developer tools and navigate to the Network tab. Filter the results by admin-ajax.php to focus solely on AJAX requests.

Admin ajax php network requests

  1. Look at the frequency of requests and their payloads. Frequent calls or large payloads can give you clues about which action is causing the load.
  2. Each AJAX request includes an action parameter (e.g., action=plugin_hook_name). This identifies the hook or function being triggered. Take note of this value.
  3. Once you’ve identified the action parameter, look it up in the plugin’s documentation or code to determine which plugin is responsible.
  4. If the plugin is unclear, disable your plugins one by one and monitor the Network tab until you see a reduction in admin-ajax.php traffic.

For a more detailed approach, use the Query Monitor plugin. The Queries by Caller column will show you which hook or function triggered the AJAX request.

Query Monitor queries by caller

For example, with the relationship field available in Advanced Custom Fields (ACF®), you might see something like this:

  • Action: acf/fields/relationship/query
  • File: advanced-custom-fields-pro/includes/fields/class-acf-field-relationship.php:585

This tells you exactly which file and line in the plugin is executing the query, making it easier to identify and optimize the problem area.

Supercharge Your Website With Premium Features Using ACF PRO

Speed up your workflow and unlock features to better develop websites using ACF Blocks and Options Pages, with the Flexible Content, Repeater, Clone, Gallery Fields & More.

Explore Features View Pricing

PRO Features
ACF Blocks
Options Pages
PRO Fields
Repeater
Flexible Content
Gallery
Clone

Decode your specific admin-ajax.php error messages

When you encounter issues with admin-ajax.php, deciphering the error messages can help you quickly pinpoint the root cause. Here’s how to locate said error messages for troubleshooting:

  1. Click a request and open its Response tab in your browser’s developer tools to view the raw error output. This will show you the server’s response to the AJAX request, including any error messages.
  2. Look for these common error codes:
    • 0 (Generic Failure) is a vague error indicating something went wrong without specific details.
    • -1 (Unauthorized) typically indicates a permission or nonce issue.
    • PHP warnings/notices can point to issues in the PHP code like undefined variables, function issues, or deprecated functions.
  3. In the request payload, locate the action parameter (e.g., action=plugin_hook_name). Trace this to the specific function hooked to that action in the theme or plugin code for a clearer idea of where the issue originates.
  4. Enable WP_DEBUG in your wp-config.php file and check the error logs for more detailed information, such as stack traces. These logs will show the exact point of failure.

Here are a few clues you might spot in the logs and what they mean:

  • Memory exhausted (e.g., acf-field-relationship.php:585) could indicate that the query is too large and exceeds the available memory. Solutions include paginating the query or implementing caching to reduce the load.
  • Max execution time (e.g., class-wpdb.php) suggests slow database joins or inefficient queries. Consider optimizing your queries or adding indexes to speed up database operations.
  • Undefined function (e.g., ajax-handlers.php) may indicate a missing include or incorrect file path. Ensure that all necessary files are loaded correctly and included at the right places in your code.
  • Nginx upstream timed out happens when the PHP worker is stuck on a slow action. It could be caused by a resource-intensive operation in the plugin or theme. Review your PHP logic or optimize slow actions.

Once you’ve identified the specific error, cross-reference it with the plugin or theme code. Common issues include faulty logic, missing or incorrect nonces, or poorly optimized database queries.

Optimize admin-ajax.php for your actual bottleneck

Most performance issues stem from specific bottlenecks that you can address if you:

  • Identify the slow action by opening your browser’s Network tab and locating the admin-ajax.php request with the longest response time. Check the action parameter in the request payload to pinpoint exactly which handler needs optimization.
  • Reduce database query load by adding indexes to frequently searched columns, implementing result caching with transients, and limiting row counts. Large datasets should use pagination instead of loading thousands of records in a single request.
  • Cut WordPress bootstrap overhead by moving non-urgent operations to wp-cron jobs or background processing queues. Heavy initialization logic doesn’t belong in AJAX handlers that need to respond quickly to user interactions.
  • Control request frequency through client-side throttling, extended Heartbeat intervals, and input debouncing. Rapid-fire requests from users or polling scripts can overwhelm your server even with optimized handlers.
  • Cache repeated results using WordPress transients for database queries, object caching for expensive computations, or static JSON files for predictable responses. Aggressive caching transforms slow dynamic requests into fast static responses.
  • Offload work by migrating high-frequency actions to REST API endpoints or custom handlers that bypass full WordPress initialization. admin-ajax.php should handle admin-specific functionality, not public-facing features.

When to migrate from admin-ajax.php to REST API

The WordPress REST API can be used as an alternative to admin-ajax.php because it provides a more flexible, modern, and scalable way to handle asynchronous requests with JSON responses, making it easier to integrate with frontend JavaScript and third-party applications.

That said, migration isn’t always necessary or beneficial. Evaluate based on your use case, since high request volume with small payloads favors REST API, while complex authentication or large data transfers may not.

Looking at performance benchmarks by experts, you’ll see REST API deliver moderately faster response times than admin-ajax.php on vanilla WordPress installations, with improvements becoming less pronounced on plugin-heavy sites. Custom must-use endpoints can achieve significantly faster response times than either option, but require more development effort.

Consider that performance gains vary significantly across different WordPress environments and plugin loads. Sites with many active plugins see smaller performance improvements when switching to REST API, while custom endpoints consistently deliver the fastest response times across all configurations.

Choose REST API when you have high request volume, small payloads, and need modern HTTP standards support. The clearer URL structure and built-in caching headers make REST ideal for public-facing functionality and mobile applications.

Maintain admin-ajax.php in parallel if you need legacy browser compatibility or have existing integrations that can’t be immediately updated. Running both endpoints during migration allows gradual rollout without breaking existing functionality.

Consider custom must-use endpoints for extreme performance requirements where neither admin-ajax.php nor REST API meets your speed needs. These bypass most WordPress initialization overhead but require more development effort and careful security implementation.

Convert existing admin-ajax handlers to REST endpoints by registering routes with register_rest_route() and updating client-side calls. For ACF relationship fields, for example, replace your admin-ajax handler:

add_action('rest_api_init', function() {

    register_rest_route('my/v1', 'acf-rel', [

        'methods' => 'GET',

        'permission_callback' => '__return_true',

        'callback' => 'my_acf_rel_rest'

    ]);

});

function my_acf_rel_rest(WP_REST_Request $request) {

    $search = sanitize_text_field($request['search']);

    $results = my_acf_relationship_query($search);

    return rest_ensure_response($results);

}

Then update your JavaScript from jQuery.post() to wp.apiFetch({path: '/my/v1/acf-rel?search=foo'}).

Plan for refactoring complexity since you’ll need to replace nonce verification with REST permissions, handle potential CORS issues, and update all client-side code. Maintaining backward compatibility during rollout often means running duplicate endpoints temporarily.

Secure your admin-ajax.php endpoints without breaking functionality

Focus your security efforts on the endpoints that actually need protection rather than applying blanket restrictions:

  • Target only high-risk actions that process sensitive data or perform destructive operations. Low-risk functionality like search suggestions or content filtering doesn’t require the same protection level as user registration or payment processing.
  • Add nonces to forms using wp_create_nonce('my_action') in your HTML and verify with check_ajax_referer('my_action') in your handler. This prevents cross-site request forgery attacks while maintaining smooth functionality for legitimate users.
  • Implement nonce fields as hidden form inputs or data attributes, then validate them before processing any requests. For contact forms, add data-nonce="<?php echo wp_create_nonce('contact_form'); ?>" to your form element and verify with check_ajax_referer('contact_form') in your PHP callback.
  • Balance security with usability by implementing nonce refresh mechanisms for logged-out users instead of hard failures. Expired nonces should trigger JavaScript to fetch a fresh nonce rather than completely blocking the user’s action.
  • Preserve anonymous access for public-facing features while still validating request legitimacy through nonces or capability checks. Contact forms and newsletter signups should remain accessible to visitors, but always verify intent before processing their data.

Your admin-ajax.php action plan for tomorrow

Admin-ajax.php can quickly become a performance bottleneck due to inefficient queries and excessive API calls. Apply our targeted optimizations to address query handling, server strain, and overall site responsiveness:

  • Optimize queries to cut slow requests, achieving up to an 80% improvement in speed. This reduces bottlenecks and ensures faster response times for both users and administrators.
  • Limit WordPress heartbeat API calls from over 30 per second down to 10–15 per second. This adjustment lowers unnecessary server chatter while maintaining real-time functionality.
  • Throttle requests to reduce simultaneous admin-ajax.php calls. This decreases server strain, stabilizes performance, and improves site reliability under traffic spikes.
  • Shift from reactive troubleshooting to a proactive, metrics-based optimization strategy. Monitoring performance trends allows you to prevent issues before they escalate and maintain consistent site health.

To get you started, here’s a phased approach that outlines a structured workflow for diagnosing, resolving, and validating admin-ajax.php performance issues, ensuring each optimization is measurable and results are clearly communicated:

PhaseAction itemDetails
Identify critical issuesCheck slow ACF queriesUse Query Monitor to identify queries >1000ms
Review Heartbeat APIMonitor for calls exceeding 30 requests per second
Analyze admin-ajax.php requestsLook for excessive requests overloading server
Identify slow database queriesFind queries that could benefit from optimization
Implement fixesOptimize ACF queriesImplement lazy loading or pagination to reduce query time
Fix Heartbeat API issuesExtend interval between requests or unhook unnecessary callbacks
Reduce high-frequency requestsThrottle or debounce requests to reduce server strain
Optimize database queriesAdd indexes or implement caching
Record metricsTrack query time improvementsMonitor reductions (e.g., 1200ms to 220ms after caching)
Monitor Heartbeat frequencyRecord before/after adjustments (e.g., >30/sec to 10-15/sec)
Communicate resultsStakeholder reportingProvide: Problem > Evidence > Fix > Time > Expected Gain

Admin-ajax.php doesn’t have to be a mystery bottleneck – if you trace requests, optimize queries, throttle frequency, and validate gains with metrics, you’ll eventually turn hidden slowdowns into clear wins. Apply our recommendations consistently, and your WordPress site will run faster, leaner, and more reliably under load.