Why Your WordPress Cron Jobs Stall and How to Get Them Running Again
Why Your WordPress Cron Jobs Stall and How to Get Them Running Again
Scheduled tasks—like publishing future posts, clearing expired transients, or sending automated emails—are the invisible workhorses of any WordPress site. When WP‑Cron stops firing, those jobs pile up, users see delayed notifications, and the site can become sluggish. This article walks you through the typical symptoms, the most common culprits, a quick diagnostic checklist, and proven fixes that get your cron back on schedule without a full rewrite.
Typical Symptoms of a Stalled WP‑Cron
1. Missed Scheduled Posts
If a post set to publish at 10 AM never appears, the cron system that should trigger publish_future_post is likely broken.
2. WooCommerce Order Emails Stop Sending
Order confirmation, shipping updates, and abandoned‑cart reminders all rely on scheduled hooks. Gaps in email flow often point to a cron issue.
3. Accumulating Transient Data
Plugins that use set_transient() for caching will leave stale entries in the database, inflating wp_options and slowing queries.
4. Admin Dashboard “Cron Events” List Is Empty
Visiting wp-admin/tools.php?page=action-scheduler (or a similar scheduler UI) shows no pending actions, even though you know tasks exist.
Common Causes Behind a Non‑Responsive WP‑Cron
1. Traffic‑Dependent Triggering Disabled
By default, WP‑Cron runs when a visitor loads a page. If your site receives very little traffic—or you’ve enabled a caching layer that serves static pages without PHP execution—the cron never gets the “heartbeat” it needs.
2. Server‑Level Cron Conflict
Many hosts recommend disabling WP‑Cron and adding a real system cron entry (e.g., */15 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron). An incorrectly configured system cron can prevent WP‑Cron from firing altogether.
3. Misbehaving Plugins or Themes
Plugins that hook into init and call wp_schedule_event() without proper cleanup can create duplicate or endless loops, causing PHP timeouts.
4. File Permission Issues
If wp-cron.php or the wp-content folder lacks execute/read permissions, the HTTP request fails silently.
5. Over‑Aggressive Caching or CDN
Page‑cache plugins (e.g., WP Rocket, W3 Total Cache) often set WP_CACHE to true, which can bypass the PHP execution path needed for WP‑Cron unless you add an exception.
Quick Diagnostic Checklist
🔧 Quick Tip: Before making any changes, create a fresh database backup. A single mis‑step in the
wp_optionstable can break scheduled tasks site‑wide.
- Confirm WP‑Cron Is Enabled
Openwp-config.phpand look fordefine('DISABLE_WP_CRON', true);. If it exists, either remove it or set it tofalsefor testing. - Trigger Manually
Visithttps://yourdomain.com/wp-cron.php?doing_wp_cronin a browser. A blank page with a200 OKresponse indicates the script runs. - Check System Cron
SSH into your server and runcrontab -l. Verify that any WP‑Cron entry points to the correct URL and uses the right PHP binary. - Inspect Plugin Scheduler Logs
If you use Action Scheduler (bundled with WooCommerce) or a similar library, view its log table (wp_actionscheduler_logs) for error messages. - Review Server Error Logs
Look for PHP fatal errors or 500 responses around the time you attempted a manual trigger.
Effective Fixes to Restore WP‑Cron Functionality
1. Re‑Enable Traffic‑Based Cron (If Feasible)
If your site gets consistent traffic, simply removing DISABLE_WP_CRON often resolves the issue. Clear any page‑cache after the change so that the next visitor runs the cron.
2. Set Up a Reliable System Cron
For low‑traffic sites, a server‑level cron is the safest route. Add the following line to your crontab (replace example.com with your domain):
*/15 * * * * /usr/bin/curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
Make sure the PHP binary path matches your server’s configuration, and test it with crontab -e followed by sudo service cron restart.
3. Exempt WP‑Cron from Caching Layers
Most caching plugins let you add a “do not cache” rule. For example, in WP Rocket you can add wp-cron.php to the “Never Cache URLs” list. If you use a CDN, create a page rule that bypasses cache for /wp-cron.php.
4. Repair File Permissions
Run the following commands from your site’s root directory:
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 644 wp-cron.php
This restores the typical WordPress permission set.
5. Isolate Problematic Plugins
Temporarily deactivate all plugins, then reactivate them one by one while monitoring the scheduler. Plugins that re‑introduce the issue should be replaced or patched.
6. Move to Managed WordPress Hosting for Built‑In Cron Reliability
If you’re juggling multiple fixes and still see intermittent failures, consider a hosting environment that handles cron jobs at the infrastructure level. Our WordPress Hosting service runs a dedicated server‑side scheduler, bypasses traffic‑dependent triggers, and integrates with automatic core updates—eliminating the most common WP‑Cron pitfalls.
7. Clean Up Stale Transients
After restoring cron, purge old transients to free database space. Run this WP‑CLI command:
wp transient delete --all
Or use a plugin like “Transients Manager” for a UI‑based cleanup.
Preventive Checklist for Future Cron Health
- Schedule a real system cron (every 15 minutes) and keep
DISABLE_WP_CRONset totrue. - Whitelist
/wp-cron.phpin every caching plugin and CDN configuration. - Monitor the
wp_optionstable size; a sudden jump often signals a stuck cron. - Enable WP‑CLI health checks (
wp cron event list) as part of your regular maintenance routine. - Keep plugins and themes up to date; outdated code is a frequent source of fatal errors that abort scheduled tasks.
Conclusion
WP‑Cron is a simple yet powerful scheduler, but its reliance on site traffic or misconfigured server cron jobs can cause silent failures. By recognizing the tell‑tale symptoms, running a focused diagnostic checklist, and applying the fixes above—especially moving to a managed WordPress environment when appropriate—you’ll keep scheduled tasks running smoothly, improve site reliability, and free yourself from chasing phantom bugs.