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:
- Go to WooCommerce → Status → Scheduled Actions
- Look for “Pending” actions that should have run
- 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.