WordPress Cron Jobs Not Running? Here's the Real Fix

Server & Cloud Intermediate 👁 9 views 📅 Jun 18, 2026

WordPress cron jobs rely on visitor traffic. If they're not triggering, the fix is usually a real server cron. Here's how to set that up and why it works.

WordPress Cron Isn't a Real Cron — That's Usually the Problem

I've seen this a hundred times: scheduled posts sit in drafts, emails don't go out, and everyone blames plugins. But what's actually happening is that WordPress uses a fake cron system. It only runs when someone visits your site. If your traffic is low or your host aggressively caches pages, the cron event never fires.

Here's the fix: disable WP-Cron and set up a real server cron job. Do this and you're done. No plugins needed, no fluff.

The Fix: Replace WP-Cron with a Server Cron

This takes five minutes and works on any Linux server with SSH access. If you use a managed host like WP Engine or Kinsta, they already do this for you — check your control panel first.

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

Add this line to your wp-config.php file, right above the /* That's all, stop editing! */ comment:

define('DISABLE_WP_CRON', true);

This tells WordPress to stop checking for cron jobs on every page load. No more wasted server resources, no more false hope.

Step 2: Set Up a Real Server Cron

Connect to your server via SSH and run crontab -e. Add this line:

* * * * * wget -q -O - https://yoursite.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Replace yoursite.com with your actual domain. That asterisk sequence means it runs every minute — same as WP-Cron's default behavior, but now it actually fires.

If your server doesn't have wget (rare but possible), use curl instead:

* * * * * curl -s -o /dev/null https://yoursite.com/wp-cron.php?doing_wp_cron

Test by waiting a minute. Check if your pending scheduled tasks are running. I usually verify by publishing a post set to "Schedule for 1 minute from now" — if it publishes, the fix worked.

Why This Works

WordPress's built-in cron (WP-Cron) is fundamentally a check, not a schedule. On each page load, WordPress runs wp-cron.php to see if any tasks are due. If you're behind a CDN or your site is cached, your pages might not trigger PHP at all. So the cron check never happens.

By disabling WP-Cron and hitting wp-cron.php from a real system cron, you guarantee that the check runs every 60 seconds regardless of traffic. The ?doing_wp_cron query parameter tells WordPress this is a cron call, not a user hitting your site directly. The redirect to /dev/null just swallows the output so you don't get mail every minute.

The reason step 2 works is that the server's cron daemon is an independent process. It doesn't care about traffic, caching plugins, or PHP memory limits. It just runs the command.

Less Common Variations of the Same Issue

Sometimes disabling WP-Cron alone isn't enough. Here are the real edge cases I've debugged:

Your Host Blocks wp-cron.php

Some cheap shared hosts intentionally block wp-cron.php to prevent resource abuse. Check your server's error log if the cron seems to fire but nothing happens. The fix: ask your host to whitelist the file, or switch to a host that doesn't play that game. I'm not a fan of hosts that break core WordPress behavior.

You're Using a Load Balancer or Multiple Web Servers

If you run WordPress across multiple servers (like with a load balancer), the cron request might hit a server that isn't running the cron job. The fix: set up the cron on one specific server, not on all of them. Use that server's internal IP for the cron URL to avoid routing issues.

Your Site Uses HTTPS with Self-Signed Certificates

If you're on a local dev environment with a self-signed cert, wget or curl might refuse to connect. Add --no-check-certificate to the wget command, or use -k with curl. But don't do this in production — use a real cert.

WP-Cron Hooks Break When Called via CLI

Some plugins assume they're being called from a browser context. If a plugin's cron hook uses a function from your theme that only loads during a full WordPress bootstrap, the cron call fails silently. The fix: wrap the hook's callback in a check for function_exists() or load the theme functions explicitly. I've seen this with WooCommerce and some custom membership plugins.

You Have a Plugin That Overrides Cron Intervals

Plugins like "Cron View" or "Advanced Cron Manager" can change how often tasks run. If you see a task scheduled for, say, once per hour but it's actually running every minute, a plugin is overriding the interval. Check wp_options table for cron option and look for unexpected intervals. Remove the interfering plugin if it's not needed.

Prevention: Keep It Running

This isn't a set-it-and-forget-it thing. Come back every few months and check that the cron is still running. I add a simple monitoring check: if a scheduled post doesn't publish within 5 minutes of its scheduled time, I get an email. You can do this with a free monitoring tool like UptimeRobot hitting a custom page that verifies the last cron run timestamp.

Also, if you ever move hosts or change your domain, update the cron URL immediately. I've seen people migrate a site, forget the cron, and lose scheduled emails for a week.

One more thing: avoid the temptation to install a "cron manager" plugin. They're almost always unnecessary. A single line in crontab is more reliable than any plugin. If you need a GUI for managing cron tasks on your server, use your host's control panel, but keep the WP-Cron layer out of it.

That's it. No more late posts, no more missing emails. Your WordPress cron will actually run.

Was this solution helpful?