75 guides published Start a blog Fix my site How we test
FIX IT

WP-Cron Is Not Running, and What Quietly Breaks Because of It

WordPress has no scheduler of its own. It fakes one by checking for due tasks whenever someone visits the site. On a low-traffic site that means tasks run late or not at all, and the failures are silent.

The short version

  • WP-Cron runs on page visits, not on a clock.
  • A low-traffic site misses scheduled tasks routinely.
  • A caching layer can prevent it running at all.
  • The fix is a real server cron job, which takes five minutes.

What breaks when it stops

  • Scheduled posts miss their schedule.
  • Backups do not run.
  • Update checks stop, so you stop seeing available updates.
  • Transients never expire, so the options table grows.
  • Email notifications and digests stop.
  • Anything a plugin schedules — feeds, syncs, cleanups — stops.

None of these produce an error. That is what makes this worth checking proactively.

Confirm it is the problem

# list scheduled events
wp cron event list

# anything overdue?
wp cron event list --fields=hook,next_run_relative | head -20

# test the runner
wp cron test

Entries with a next run in the past are overdue. A few seconds late is normal; hours or days is not.

Why it fails

CauseHow to tell
Low trafficFew visits, tasks run very late
Page cachingCached pages never execute PHP, so cron is never triggered
DISABLE_WP_CRON set with no replacementSomeone disabled it and never added a server cron
Loopback request blockedA firewall or basic auth blocking the site calling itself
A stuck long-running taskOne failing task blocks the queue behind it

The loopback problem

WP-Cron works by the site making an HTTP request to itself. If HTTP authentication is enabled, or the server cannot resolve its own domain, that request fails silently. Test it:

curl -sI https://example.com/wp-cron.php?doing_wp_cron | head -3

You should get a 200. A 401 means basic authentication is blocking it — common on staging sites, where it is harmless, and occasionally left on in production, where it is not.

The proper fix: a real cron job

Disable the visit-triggered version and schedule it on the server instead:

// wp-config.php
define( 'DISABLE_WP_CRON', true );
# crontab -e  — every five minutes
*/5 * * * * cd /path/to/wordpress && /usr/local/bin/wp cron event run --due-now --quiet

# or, if WP-CLI is not available
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

The WP-CLI version is better: it runs as a real process without a web-server timeout, and it bypasses any caching or authentication in front of the site.

Watch out

Setting DISABLE_WP_CRON without adding a server cron job stops scheduled tasks entirely. Always add the cron entry in the same session.

Clearing a stuck queue

One task that fatals every time it runs can block everything behind it:

# see what is scheduled
wp cron event list

# run a specific hook and watch for an error
wp cron event run some_stuck_hook

# remove a hook that should not be there
wp cron event delete some_stuck_hook

Hooks belonging to plugins you removed are a common cause. The plugin is gone, the schedule is not, and the hook fires into nothing.

Verify it is working

  1. Schedule a post five minutes ahead and confirm it publishes on time.
  2. Run wp cron event list and check nothing is overdue.
  3. Check your backup plugin’s log the next day.

Common questions

Does disabling WP-Cron make the site faster?

Marginally, by removing a check on each page load. The real reason to do it is reliability.

Every five minutes — is that too often?

No. The command exits immediately when nothing is due.

My host says they run cron for me

Verify it. Schedule a post and see whether it publishes on time.

S

Sumit

Writes everything on TechMozz.

More in Fix It