Technical

WP-Cron Not Working: Scheduled Tasks Never Run (2026)

By Daniel Reyes•October 31, 2026•3 min read

Disclosure: some links on this page are affiliate links. We may earn a commission at no extra cost to you. How we test and rate hosts.

Our top pick for most WordPress sites
Bluehost: free domain, free SSL, 24/7 support, 30-day money-back guarantee.
Check Bluehost Deal →

wp-cron isn't a real cron job - it's a timer that only fires when someone loads a page. That's why it fails two ways: silently on quiet sites (no visitors = no trigger) and destructively on busy ones (every visitor triggers a check, spawning concurrent runs that choke the server). The fix is the same: replace the pseudo-cron with a real one.

Symptoms: Is Your Cron Actually Broken?

  • Scheduled posts showing "Missed schedule" (see the missed schedule guide)
  • Backups, plugin updates, or stats jobs that silently skip
  • WP Crontrol or Site Health shows events overdue by hours/days
  • WooCommerce scheduled actions piling up unfinished

Step 1: Disable the Pseudo-Cron

In wp-config.php, above "That's all, stop editing":

define('DISABLE_WP_CRON', true);

This stops wp-cron firing on every pageview - which on a busy site was spawning overlapping runs. Now nothing triggers it. That's intentional; step 2 puts it on a real schedule.

Step 2: Set Up a Real Cron Job

In cPanel → Cron Jobs (or your host's equivalent), add:

*/15 * * * * curl -s https://yourdomain.com/wp-cron.php?doing_wp_cron

Every 15 minutes works for most sites. For WooCommerce or heavy scheduling, go every 5. Your scheduled tasks now fire on a clock, not on traffic.

Step 3: Check for Blocks

If the real cron still fails: wp-cron.php is an HTTP request your server makes to itself - a "loopback" request. Security plugins, WAF rules, and hosts that block loopback connections kill it. Whitelist wp-cron.php in your firewall. Test manually: load https://yourdomain.com/wp-cron.php?doing_wp_cron in a browser - it should return a blank 200 page, not an error.

When wp-cron WAS the Problem All Along

On busy sites, the pseudo-cron was creating load: every pageview triggered a cron check, and heavy jobs (backups, WooCommerce) collided and ran concurrently - the same resource exhaustion behind 503 errors and 429 rate limits. DISABLE_WP_CRON + a real cron doesn't just fix schedules - it reduces server load measurably.

Managed Hosts Handle This For You

Properly managed WordPress hosting already runs wp-cron on a real system schedule - no config, no missed schedules, no pseudo-cron overhead. If your host makes you fix this manually, that's the tier you're paying for.

See Bluehost →

Keep Reading

Find Your Perfect Hosting Plan

What are you building?

Tell us about your project so we can match the perfect hosting plan.

Question 1 of 425% complete
Interactive Tool

Hosting Cost Calculator

See exactly how much you'll spend on hosting over time. Compare Bluehost vs popular alternatives and discover your potential savings.

Used to calculate transaction fees (Shopify charges 2% on sales)

Shopify Basic (3yr)
$1,044
Bluehost (3yr)
$444
You Save
$600
58% less than Shopify Basic

Frequently Asked Questions

How do I know if wp-cron is broken?

Symptoms: scheduled posts stuck in 'Missed schedule,' backups/updates that never fire, cron events listed as overdue in a plugin like WP Crontrol, or a Site Health warning 'A scheduled event has failed.' Check Tools → Site Health → Scheduled Events for a queue that's hours or days behind.

Why does wp-cron fail on low-traffic sites?

wp-cron isn't a real cron - it only runs when someone visits a page. Zero traffic = zero cron = missed schedules, skipped backups, stale caches. A site with no visitors is a site where scheduled tasks simply never trigger.

What does DISABLE_WP_CRON do?

define('DISABLE_WP_CRON', true) stops the front-end trigger so wp-cron doesn't fire on every pageview - essential because the pseudo-cron adds a check on every request and, under load, spawns concurrent runs that can overwhelm a server. You replace it with a real server cron hitting wp-cron.php on a schedule.

What's the correct real cron command?

In your host's cron panel (cPanel 'Cron Jobs' or SSH crontab): */15 * * * * curl -s https://yourdomain.com/wp-cron.php?doing_wp_cron - every 15 minutes is plenty for most sites. With DISABLE_WP_CRON set, this is now the only trigger, which is exactly what you want.

Can a plugin or server block wp-cron?

Yes - security plugins and firewalls that block loopback requests (your server calling itself) break wp-cron, which is an HTTP request to your own domain. Whitelist wp-cron.php in the firewall. Also check that your host allows loopback - some cheap hosts block it and wp-cron fails silently.

Ready to launch?

Get Bluehost from $3.99/month with a free domain, free SSL, and 30-day money-back guarantee.

Start for $3.99 →

Related Articles