WordPress admin-ajax.php high CPU? Name the action

Fictional request: a logged-in dashboard request reaches admin-ajax.php with the action field set to example_report. That action is the useful clue. The shared admin-ajax.php filename only tells you which WordPress entry point received the request. It does not tell a Dubai, Liverpool or UK business which plugin, theme feature or custom dashboard widget is actually doing the work.

Abstract request routing diagram showing one overloaded action path

When server logs show a busy admin-ajax.php endpoint, teams often jump straight to Heartbeat, disable it broadly, and hope the CPU graph calms down. Sometimes Heartbeat is involved. Often it is a reporting widget, page builder panel, WooCommerce extension, form integration or a bit of old custom code polling far more often than anyone realised.

Name the action before blaming the endpoint. WordPress uses the submitted action field to select the relevant wp_ajax_{$action} hook for logged-in AJAX requests, as documented in the WordPress AJAX hook reference. That routing behaviour gives you an attribution route. It does not prove an action is expensive, but it tells you where to investigate.

The endpoint is shared. The request pattern is not.

admin-ajax.php is not a plugin. It is a WordPress core endpoint used by various features to send background requests. A log summary that lists only that endpoint is a bit like a building register showing everyone entered through the front door. Useful, but not enough to identify who left the heating on all weekend.

Start by collecting a short sample from the affected period. Do not make five performance changes first, as that ruins the evidence. You want request details that let you group similar calls and compare their behaviour.

What to group Why it matters Useful evidence
Action Identifies the WordPress route being requested action=example_report
Frequency Shows whether a feature polls every few seconds or only on a user event Requests per minute by action
Duration Separates a busy but quick request from a slow callback Upstream or application response time
Session or user context Shows whether one role, browser session or dashboard screen triggers it Sanitised user role, session hash, referer path
Status and response size Helps spot retries, errors and unexpectedly heavy responses HTTP status and response bytes

Do not send real cookies, nonces, customer details, full POST bodies or IP addresses around in a ticket. A sanitised sample should preserve the action, timing, frequency, status, relevant page path and a safely anonymised session marker.

Build an action inventory, not a URL inventory

Take the repeated requests from access logs, application monitoring or browser network tools and group them by action. The action field may be visible in POST data, browser developer tools or application-level logging, depending on how the site is hosted.

In the fictional example, a manager says the WordPress dashboard slows down every time the reporting screen is opened. The server summary says only admin-ajax.php. A closer look shows example_report firing repeatedly from that screen, taking longer than the other requests and occurring only during one administrator session. That points towards the reporting feature, not WordPress core as a whole.

Compare it with ordinary Heartbeat activity

Heartbeat is one possible action, commonly associated with checks that support editing and dashboard behaviour. Its presence is not an automatic verdict. Compare its recurrence and duration against other actions in the same period. A modest recurring request that completes quickly is a different issue from a custom report request that triggers large database work every few seconds.

Blanket restrictions can interfere with editing, autosaves or customer-facing interactions while the costly callback carries on elsewhere. It is a poor trade for a business that needs staff to update pages, process orders or respond to enquiries.

Trace the action back to its owner

Once you have an action name, search the active theme, must-use plugins, standard plugins and custom snippets for that name. Look for the server-side AJAX registration and the browser-side request that calls it. The owner may be obvious from a plugin folder, or it may be old bespoke work added during a previous website build.

Check the feature’s settings and update history as well. A plugin updated during business hours, an abandoned reporting add-on, or a dashboard integration querying an external API can all change the request pattern. The last function visible in a slow trace may only be where PHP ran out of patience, so follow the full callback path before declaring a culprit.

If the whole admin area is sluggish, including screens with no suspicious AJAX pattern, widen the investigation carefully. The distinction between hosting pressure and a WordPress-side problem is covered in this guide to separating a slow WordPress admin from a host issue. For a broader repair route where several faults may be overlapping, see the WordPress website repair support approach.

Test one scoped change against the responsible callback

After identifying a likely owner, test the smallest reversible change you can make. That might mean disabling one reporting widget on a staging copy, reducing its polling interval where the feature supports it, correcting an expensive query, or preventing a dashboard panel from loading for users who do not need it.

  1. Record the original action frequency and duration during a controlled session.
  2. Apply one scoped change in staging or a suitable low-risk maintenance window.
  3. Repeat the same dashboard route with the same user role and browser state.
  4. Compare the action count, duration and the feature’s actual behaviour.
  5. Retest editing, autosaves, checkout or account interactions if the changed feature could affect them.

A clean result is not merely a lower CPU reading. The expensive action should reduce or disappear for a known reason, while the business task still works. That is the bit that gets missed when somebody simply installs another performance plugin and calls it a day.

If you need a more structured route through an already slow dashboard, this slow WordPress admin dashboard diagnosis helps separate the AJAX finding from wider database, plugin and hosting checks.

The evidence threshold for escalation

Escalate when you can show an action name, its recurrence, approximate duration, affected session or screen, and what happened after a controlled test. That gives a developer or host something concrete to inspect instead of a vague report that admin-ajax.php is using CPU.

Send a sanitised request sample and its action name so Standish Services can investigate the feature behind the load.