How to Fix WordPress Cron Jobs Not Running (WP-Cron)

You schedule a post for 8 AM. 8:01 comes… nothing. 9 AM… still nothing. Your “scheduled” post sits there like a forgotten promise.

Or your backup plugin swears it runs daily, but you check and the last backup was three weeks ago.

Welcome to the world of broken WordPress cron jobs. WP-Cron (WordPress’s pseudo-cron system) is notorious for being unreliable, yet it’s essential for everything from publishing to security scans.

I’ve fixed cron issues on everything from blogs to enterprise WooCommerce stores. The solution ranges from simple to “replace the entire system.” Let’s get your automation working.


How WP-Cron Actually Works (And Why It Fails)

Unlike server cron jobs that run at specific times, WP-Cron only runs when someone visits your site. No visitors = no cron execution.

Common failure points:

  • Low traffic sites (cron only runs when you visit)
  • Caching plugins (prevent WordPress from loading, blocking cron)
  • Server timeouts (cron tasks take too long)
  • Plugin conflicts (multiple cron jobs fighting)
  • Missed schedules (race conditions)

[IMAGE PLACEHOLDER: Diagram showing WP-Cron execution flow: Visitor request → WordPress loads → WP-Cron checks for due tasks → Executes if found]


Method 1: Disable Caching for WP-Cron (Quick Fix)

Caching plugins often block cron execution because they serve static HTML without loading WordPress.

For WP Rocket:

  • Go to WP Rocket → Cache → Advanced Rules
  • Add to “Never Cache URL(s)”:

Copy

/wp-cron.php

/(.*)sitemap(.*).xml

For W3 Total Cache:

  • Performance → Page Cache → “Never cache the following pages”
  • Add:

Copy

wp-cron.php

wp-admin*

For SiteGround Optimizer:

  • Exclusions → URL Exclusions
  • Add wp-cron.php

For Cloudflare:

  • Rules → Page Rules
  • Create rule for *yoursite.com/wp-cron.php*
  • Settings: Cache Level = Bypass

Alternative: Add this to wp-config.php to disable cron during page loads and call it directly:

php

Copy

define(‘DISABLE_WP_CRON’, true);

Then set up a real cron job (see Method 4).


Method 2: Fix Plugin Cron Conflicts

Too many plugins scheduling tasks = chaos.

Step 1: Install WP Crontrol plugin (free, lightweight).

Step 2: Go to Tools → Cron Events. Look for:

  • Duplicate hooks (same task scheduled multiple times)
  • Missed schedules (red “Past Due” indicators)
  • Excessive frequency (tasks running every minute unnecessarily)

Step 3: Delete duplicate or stuck cron jobs. Be careful not to delete WordPress core hooks like wp_version_check.

Step 4: Identify heavy tasks. Look for hooks from:

  • Backup plugins (UpdraftPlus, BackupBuddy)
  • Security scanners (Wordfence, Sucuri)
  • SEO plugins (Yoast, RankMath)
  • WooCommerce (cleanup tasks, webhooks)

Step 5: Stagger schedules. If everything runs at midnight, spread them out:

  • Backups: 2 AM
  • Security scans: 4 AM
  • Database cleanup: 6 AM

[IMAGE PLACEHOLDER: Screenshot of WP Crontrol plugin showing cron events list with hooks, schedules, and next run times]


Method 3: Increase PHP Time Limits

Cron jobs fail silently when they hit PHP time limits.

Step 1: Edit wp-config.php:

php

Copy

set_time_limit(300); // 5 minutes

Step 2: If you have access to php.ini:

ini

Copy

max_execution_time = 300

max_input_time = 300

memory_limit = 512M

Step 3: For shared hosting, add to .htaccess:

apache

Copy

php_value max_execution_time 300

php_value memory_limit 512M

Step 4: For NGINX, add to nginx.conf:

nginx

Copy

location ~ \.php$ {

    fastcgi_read_timeout 300;

}

Why This Matters: Backup plugins especially need time to zip large files. If they timeout, the cron job never completes and schedules fail.


Method 4: Replace WP-Cron with Real Server Cron (The Permanent Fix)

This is the gold standard for reliability.

Step 1: Disable WP-Cron in wp-config.php:

php

Copy

define(‘DISABLE_WP_CRON’, true);

Step 2: Set up server cron via cPanel or SSH.

For cPanel:

  • Go to cPanel → Advanced → Cron Jobs
  • Add new cron job:

*/5 * * * * cd /home/username/public_html; php -q wp-cron.php >/dev/null 2>&1

For SSH/Crontab:

bash

Copy

crontab -e

Add:

*/5 * * * * cd /var/www/html && php wp-cron.php >/dev/null 2>&1

Explanation:

  • */5 = Every 5 minutes
  • cd = Change to WordPress directory
  • php wp-cron.php = Execute cron file
  • >/dev/null 2>&1 = Suppress email notifications

Step 3: Verify it’s working. Install WP Crontrol and check that “Next Run” times are updating.

For VPS/Cloud Servers (Systemd Timer): Create /etc/systemd/system/wordpress-cron.service:

ini

Copy

[Unit]

Description=WordPress Cron

[Service]

Type=oneshot

ExecStart=/usr/bin/php /var/www/html/wp-cron.php

Create /etc/systemd/system/wordpress-cron.timer:

ini

Copy

[Unit]

Description=Run WordPress Cron every 5 minutes

[Timer]

OnCalendar=*:0/5

Persistent=true

[Install]

WantedBy=timers.target

Enable:

bash

Copy

systemctl enable wordpress-cron.timer

systemctl start wordpress-cron.timer


Method 5: Fix Specific Cron-Dependent Features

Scheduled Posts Not Publishing:

Add to wp-config.php as a temporary fix:

php

Copy

define(‘ALTERNATE_WP_CRON’, true);

This uses a redirect method that’s less reliable but works on some problematic hosts.

WooCommerce Webhooks Failing:

WooCommerce relies on Action Scheduler (built on WP-Cron). If webhooks aren’t firing:

  1. Go to WooCommerce → Status → Scheduled Actions
  2. Look for “Pending” actions that should have run
  3. If they’re stuck, run:

sql

Copy

DELETE FROM wp_actionscheduler_actions WHERE status = ‘pending’ AND scheduled_date_gmt < DATE_SUB(NOW(), INTERVAL 1 DAY);

Then restart the queue.

Backup Plugins Missing Schedules:

Most backup plugins have a “Run Now” button. Use server cron to trigger backups directly instead of relying on WP-Cron:

bash

Copy

# For UpdraftPlus CLI (if available)

/usr/bin/php /var/www/html/wp-content/plugins/updraftplus/updraftplus.php backup

Or use the plugin’s remote trigger URL in a server cron job.


FAQs: Cron Clarity

Will disabling WP-Cron break my site?

No. You’re replacing it with a more reliable system. All scheduled tasks still run; they just use server cron instead of visitor-triggered cron.

How do I know if cron is working?

Install WP Crontrol. If “Next Run” times are in the future and updating, it’s working. Or check if scheduled posts publish on time.

Can I run cron less frequently than 5 minutes?

Yes, but WordPress recommends at least every 5 minutes. For high-traffic sites, every minute is fine. For low-traffic blogs, every 15 minutes is sufficient.

Why do some hosts block WP-Cron?

Some shared hosts disable wp-cron.php execution to save resources. That’s why Method 4 (server cron) is necessary for reliability.

Does this affect WooCommerce Subscriptions or Memberships?

Yes, critically. These plugins rely on cron for renewals, expirations, and emails. If cron is broken, you lose revenue. Prioritize fixing this if you run subscription sites.


Conclusion: Cron You Can Count On

WP-Cron is WordPress’s Achilles heel—brilliant in concept, fragile in execution. By implementing server-level cron jobs, you’ve replaced a visitor-dependent system with a clockwork-precise one.

Your Reliability Checklist:

  • [ ] WP-Cron disabled in wp-config.php
  • [ ] Server cron job running every 5 minutes
  • [ ] PHP time limits increased for heavy tasks
  • [ ] WP Crontrol installed for monitoring
  • [ ] Staggered schedules to prevent conflicts

Scheduled posts will publish. Backups will run. Memberships will renew. Your site will do what it’s supposed to do, when it’s supposed to do it.

That’s the power of reliable automation.

About the Author

Leave a Reply

Your email address will not be published. Required fields are marked *

You may also like these