14+ years building on WordPress / Replies in under 5 hours
Troubleshooting 5 min read · Updated August 2026

WP-Cron Not Running? How to Fix Scheduled Tasks in WordPress

Photo of Ajay Khandal
Ajay Khandal
WordPress Developer
A stopped mechanical clock resting on a laptop keyboard lit by green screen glow, symbolizing WordPress scheduled tasks that silently stop firing
TL;DR

WP-Cron isn't a real background service — it only checks for due tasks on page load, so a quiet site can leave scheduled posts, backups, and emails sitting undone for hours. Confirm it's broken via Tools → Site Health, check for blocked loopback requests and conflicting wp-config.php constants (DISABLE_WP_CRON, ALTERNATE_WP_CRON), then replace the page-load trigger with a real server cron job hitting wp-cron.php every 5-15 minutes.

If your WordPress scheduled posts are publishing hours late, your backup plugin keeps skipping its nightly run, or WooCommerce abandoned-cart emails just stop going out, the cause is almost always the same: WP-Cron isn’t firing reliably. This guide walks through confirming that, finding the real cause, and setting up a fix that actually holds.

What WP-Cron actually is (and why it’s not a real cron job)

Despite the name, WP-Cron isn’t a background service running on a schedule — it’s a script, wp-cron.php, that WordPress checks on every single page load. If it’s been long enough since the last check, WordPress fires off any scheduled tasks that are due. This works fine on a busy site with constant traffic. It breaks down on a low-traffic site, because if nobody visits the site for six hours, nothing due in those six hours runs until someone finally does.

How to tell WP-Cron is actually broken

Look for more than one of these at once:

  • Scheduled/future posts publish late, or sit stuck in “Scheduled” status past their publish time
  • Backup plugins report a missed or delayed run
  • WooCommerce order emails, abandoned-cart emails, or subscription renewals fire late or not at all
  • Cached content doesn’t clear on the schedule you configured
  • WordPress’s own Tools → Site Health screen flags a scheduled-event problem under the Info tab’s “WordPress Cron” section

Step 1: Confirm it’s actually broken

Check Tools → Site Health → Info → WordPress Cron first — it shows whether WP-Cron is running via the default page-load trigger, whether it’s disabled, and the timestamp of the last successful spawn. If that timestamp is hours or days old on a site that’s getting regular traffic, something is actively blocking it, not just a quiet-traffic gap.

Step 2: Check for blocked loopback requests

Every WP-Cron trigger works by WordPress making an HTTP request back to itself — a “loopback” request. If your host, firewall, or a security plugin blocks the server from calling its own domain, every cron trigger silently fails before it even checks what’s due. Site Health’s “REST API availability” and general loopback checks under the same Info tab will flag this if it’s the cause; if you’re on shared hosting behind a strict WAF or your host has SSL/TLS misconfigured for internal requests, this is the most common single cause of WP-Cron going quiet.

Step 3: Check wp-config.php for conflicting constants

Two constants directly control this behavior and are easy to forget about once a developer sets them and moves on:

  • define( 'DISABLE_WP_CRON', true ); — turns off the page-load trigger entirely. Intentional if you’ve already set up a real server cron job (see Step 5); a problem if it’s set and nothing replaced it.
  • define( 'ALTERNATE_WP_CRON', true ); — changes how the loopback request fires, sometimes added as a workaround for a hosting quirk and then forgotten. Can itself cause issues on hosts it wasn’t actually needed for.

Search your wp-config.php for both before assuming the problem is elsewhere.

Step 4: Check for HTTP basic auth blocking wp-cron.php

If your staging site (or a password-protected production site) has HTTP basic authentication enabled at the server level, that login prompt blocks WordPress’s own loopback request to wp-cron.php just as it would block a browser. If you have file access, exclude wp-cron.php specifically from the basic-auth rule rather than disabling protection for the whole site.

Step 5: Set up a real server-side cron job (the permanent fix)

The page-load trigger is a reasonable default, but for anything with real scheduled tasks — WooCommerce, scheduled publishing, nightly backups — a real cron job is worth the five minutes it takes:

  1. Add define( 'DISABLE_WP_CRON', true ); to wp-config.php, above the line that says “That’s all, stop editing.”
  2. In your host’s cPanel/cron manager (or via SSH), add a job that runs every 5-15 minutes. With WP-CLI available: */10 * * * * cd /path/to/site && wp cron event run --due-now >/dev/null 2>&1. Without WP-CLI: */10 * * * * wget -q -O - https://yoursite.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1.
  3. Confirm the job actually ran by checking Site Health’s last-spawn timestamp again after the interval passes.

This is the same background-task pattern covered in more depth in our guide on offloading heavy tasks with asynchronous background processing — worth reading if you’re building a plugin that schedules its own recurring jobs, not just fixing an existing one.

Step 6: Verify scheduled events are actually running

Install WP Crontrol (or a similar cron-inspection plugin) to see the actual list of scheduled hooks, their next-run time, and run them manually to confirm they complete without errors. This is also how you catch a plugin that scheduled a duplicate or runaway recurring event, which shows up as a wp-cron slowdown that looks identical to a broken trigger but has a completely different fix.

When this is a symptom of a bigger hosting problem

If loopback requests are blocked, that’s not only a cron problem — it can affect scheduled backups (see our backup and disaster recovery guide for why a verified backup schedule matters, not just a configured one) and any plugin that depends on WordPress talking to itself. If you’ve worked through all six steps and scheduled tasks are still unreliable, that usually points to a hosting environment that needs a proper look rather than another plugin — this is exactly the kind of thing covered under ongoing WordPress maintenance, where someone is actually watching whether your scheduled tasks ran, not just whether the site loads.

Frequently asked questions

WP-Cron is a WordPress script that checks for due scheduled tasks on every page load, not a background service running independently on a timer like a real system cron job. On low-traffic sites this means due tasks can sit unrun for hours until someone happens to visit.

The most common cause is WP-Cron's page-load trigger not firing often enough on a low-traffic site, or the loopback request that triggers it being blocked by your host or a security plugin. Setting up a real server cron job on a fixed interval fixes both.

WooCommerce order emails, abandoned-cart reminders, and subscription renewals all run through the same WP-Cron scheduling system as everything else in WordPress, so a broken cron trigger delays or drops them exactly like it does scheduled posts.

A plugin like WP Crontrol helps you see and manually run scheduled events, which is useful for diagnosis, but the actual fix for unreliable timing is a real server-side cron job, which needs access to wp-config.php and your host's cron manager, not just a plugin.

Not directly, but it can delay security-relevant scheduled tasks like automatic update checks and scheduled malware scans, which turns a scheduling problem into a real exposure window if it goes unnoticed long enough.

Add define( 'DISABLE_WP_CRON', true ); to wp-config.php, then add a job in your host's cron manager that runs every 5-15 minutes and calls wp-cron.php directly, either via WP-CLI's wp cron event run --due-now or a wget/curl request to the wp-cron.php URL.

Photo of Ajay Khandal

Written by Ajay Khandal

I'm a freelance WordPress developer with 14+ years of experience building, fixing, and speeding up sites for businesses, agencies, and store owners across the US, UK, Europe, and Australia. I specialize in custom themes, WooCommerce, and performance — the kind of work that shows up as faster load times and fewer support tickets. No account managers, no outsourced tickets — you work directly with me, with replies typically inside 5 hours.

Work with me →