CDN & Caching Strategies

admin-ajax.php Is Slowing Your WordPress Site: Find and Fix It

If your WordPress admin feels sluggish, your server load is mysteriously high, or your speed tests show slow backend responses, there is a good chance the culprit is a file you have never thought about: admin-ajax.php.

This unassuming file is WordPress’s AJAX endpoint: the doorway plugins use for background tasks like autosaving, checking for updates, and live notifications. The problem: every request to it loads the entire WordPress core, and some plugins hammer it constantly. This guide shows you how to find out if admin-ajax.php is your problem, identify the exact culprit, and fix it, without breaking anything.

Quick note on method: this is a diagnostic workflow, not a benchmark. Every site’s plugin mix is different, so the goal is to find your specific offender, not to quote universal numbers.

The Quick Verdict

Short on time? Here is the summary:

  • admin-ajax.php itself is not the villain. It is a messenger. The real problem is almost always a plugin (or the Heartbeat API) calling it too often or doing too much work per call.
  • Find the culprit with Query Monitor or your browser’s DevTools Network tab, filtered to admin-ajax.
  • Fix it by taming the Heartbeat API, reconfiguring or replacing the offending plugin, and adding object caching so each call costs less.
  • Never just block admin-ajax.php: carts, forms, and half the admin area depend on it.

What admin-ajax.php Actually Does

WordPress is built for page loads, but modern plugins need background communication: autosaving a draft, checking whether someone else is editing a post, polling for new notifications, validating a form field. admin-ajax.php is the standard endpoint for all of it.

Here is the catch: unlike a cached page (which can skip PHP entirely), every admin-ajax.php request boots the full WordPress stack: core, theme, all active plugins, and the database connection. One request is cheap. But when a plugin fires one every 15 seconds for every logged-in user and every visitor, the cost multiplies fast:

  • 10 logged-in users × a heartbeat every 15 seconds = 40 full WordPress boots per minute, doing nothing useful most of the time
  • A badly coded plugin polling on the frontend adds the same load from visitors, who cannot even benefit from it

That is why admin-ajax.php shows up in server resource graphs and “time to first byte” complaints far more than its humble name suggests.

Step 1: Confirm admin-ajax.php Is the Problem

Method A: Browser DevTools (2 minutes, no plugin needed)

  1. Open your site (or wp-admin) in Chrome/Firefox.
  2. Open DevTools (F12) → Network tab.
  3. In the filter box, type admin-ajax.
  4. Watch for 30–60 seconds. Each row is one request — note the Time column and how often new rows appear.
  5. Click any row → Payload tab → look for the action parameter. That action name usually reveals the plugin (e.g., heartbeat, or a plugin-specific prefix).

If you see requests every few seconds with meaningful response times, you have found a live problem. If the Network tab is quiet, your issue lies elsewhere.

Method B: Query Monitor (more detail)

Install the free Query Monitor plugin, then load the affected pages. Its overview shows slow database queries and HTTP API calls, and the request timing helps you see whether AJAX handling is where time goes. It is the fastest way to connect “slow” to a specific component.

Method C: Server access logs

If you have log access, count admin-ajax.php hits over an hour. A healthy site shows modest numbers; a sick one shows thousands. This is the most honest measurement because it includes all visitors, not just your test browser.

Step 2: Identify the Culprit

Match the action parameter from DevTools to these usual suspects:

Symptom Likely culprit What to check
Requests every 15–60s in wp-admin Heartbeat API Post editor, dashboard widgets
Constant frontend polling Live chat, notification, or “recent activity” plugin Plugin settings for refresh intervals
Slow single calls (seconds each) Plugin doing heavy work per request (stats, related posts, security scans) Query Monitor’s slow-query list
Spikes on specific pages Page builder or form plugin with autosave/preview polling Editor/preview settings
High admin-ajax in access logs, low in your browser Affects logged-in users or specific roles broadly Any plugin with per-user polling

The Heartbeat API deserves special attention: it is WordPress core (not a plugin), it runs in the post editor and dashboard by default, and on sites with many editors it is often the single biggest admin-ajax consumer.

Step 3: Fix It (In Order of Impact)

1. Tame the Heartbeat API

You do not need to nuke it. The editor genuinely uses it for autosave and post locking. Instead, control where and how often it runs:

  • Install Heartbeat Control (free) or use the heartbeat settings in WP Rocket / Perfmatters if you already run one.
  • Sensible starting point: disable heartbeat on the frontend entirely (visitors never need it), slow it in the admin dashboard (e.g., 60 seconds), and leave it normal in the post editor where autosave matters.
  • Verify: watch DevTools again — frontend admin-ajax traffic should drop to near zero.

2. Reconfigure the offending plugin

For plugin-driven polling, open that plugin’s settings and look for anything like “refresh interval,” “live updates,” “check every X seconds,” or “real-time.” Options, in order of preference:

  1. Increase the interval (every 5 minutes instead of every 15 seconds).
  2. Disable the polling feature if you do not use it (do you really need live dashboard notifications?).
  3. Replace the plugin with one that uses a more efficient mechanism — or with no plugin at all, if the feature was marginal.

3. Make each call cheaper with object caching

You cannot always stop the calls, but you can make them cost less. An object cache (Redis or Memcached) means repeated database queries inside those AJAX handlers get served from memory instead of MySQL. It does not fix a chatty plugin, but it can cut the per-request cost dramatically, especially under many simultaneous users. Our Redis setup guide covers this.

4. Fix it properly: move work out of the request

For developers: the durable fix for a heavy custom AJAX handler is to not do the heavy work inside the request at all. Schedule it via WP-Cron, cache the result in a transient, and have the AJAX call read the cached result. If a plugin you rely on is the offender and the author will not fix it, that is a strong signal to switch plugins.

What NOT to Do

  • Do not block admin-ajax.php in .htaccess, Cloudflare, or a security plugin. WooCommerce carts, contact forms, the block editor, and countless plugin features break instantly. And the breakage is confusing to diagnose.
  • Do not disable the Heartbeat API entirely unless you understand the tradeoff: you lose editor autosave and post-lock warnings. Tame it per-location instead.
  • Do not install five “disable heartbeat” plugins at once. One control point is enough; overlapping plugins create the same class of conflict as overlapping cache plugins.

Who This Matters Most For

  • Membership/community sites: many logged-in users = many heartbeat and polling requests. Taming heartbeat is often the single biggest admin-side win.
  • WooCommerce stores: cart fragments use admin-ajax on every page load for logged-in users — make sure fragment caching and object caching are in place, and do not let a chatty plugin add to it.
  • Multi-author blogs: the post editor is heartbeat central. Per-location heartbeat control pays off immediately.
  • Everyone: frontend polling from a plugin you barely use is pure waste. Audit with DevTools once a quarter.

Frequently Asked Questions

Is admin-ajax.php a security risk?

It is a common target for brute-force probing because it is always present, but the file itself is not a vulnerability — the risk is poorly-coded plugin actions that fail to check permissions. Keep plugins updated, and the performance fixes in this guide do not change your security posture either way.

Why is admin-ajax.php slow even with no visitors?

Because most of its traffic comes from logged-in users and the admin area, not visitors. Heartbeat in the editor, dashboard widgets polling, and admin-side plugin features all fire with zero frontend traffic. Check DevTools while sitting in wp-admin doing nothing — that is the honest test.

Can caching fix slow admin-ajax.php?

Page caching does not apply — AJAX responses are dynamic and uncacheable by nature. Object caching (Redis/Memcached) helps by making each call’s database work cheaper. The real fix is reducing call frequency and per-call work, as described above.

What is a normal admin-ajax.php request rate?

There is no universal number, but as a rule of thumb: on the frontend for logged-out visitors it should be near zero; in the post editor, heartbeat every 15–60 seconds is normal; constant sub-15-second polling from any single source is worth investigating.

I disabled a plugin and admin-ajax.php is still busy — now what?

Clear your browser cache and check in an incognito window (a cached page can keep calling a removed plugin’s endpoint until refreshed). Then re-run the DevTools filter and read the action parameters fresh — there may be more than one culprit, which is common.

The Bottom Line

admin-ajax.php is a symptom, not the disease. Spend 10 minutes with DevTools filtered to admin-ajax, read the action parameters, and you will almost always find one plugin, or the Heartbeat API, doing the damage. Tame the heartbeat per location, calm down or replace the chatty plugin, add object caching so remaining calls cost less, and never “fix” it by blocking the file. Your server (and your editors) will thank you.