Why WordPress scheduled tasks fail silently
A scheduled post that never goes live. An order confirmation that never arrives. A nightly backup that has not run in three weeks. These have one thing in common: they all depend on WordPress cron, and WordPress cron fails without making a sound.
The frustrating part is that nothing looks broken. No error on the screen, no warning in the dashboard, no email. The task simply does not happen, and you find out when a client asks why their newsletter never went out. So it is worth understanding how this actually works, and why it breaks more often than people expect.
wp-cron is not really cron
On a real server, cron is a scheduler that runs in the background on a fixed clock. WordPress does not use that by default. What it calls cron, wp-cron, is faked. There is no background clock.
Instead, every time someone loads a page, WordPress checks whether any scheduled tasks are due, and if they are, it fires off a quick background request to a file called wp-cron.php to run them.
That design has one big assumption baked into it: that your site gets steady traffic. The schedule only moves forward when visitors show up to push it. On a busy site you barely notice. On a quiet site, a staging copy, or a client brochure site that gets ten visits a day, tasks can sit waiting for hours because nobody came by to trigger them.
The ways it quietly breaks
Low traffic is only the first way. There are a few others, and none of them announce themselves.
Someone sets define('DISABLE_WP_CRON', true) in wp-config to take load off the site, which is good practice, then forgets to set up a real system cron to replace it. Now nothing runs at all, ever.
This is probably the most common cause, because the first half of that advice travels further than the second half.
Loopback requests get blocked. wp-cron works by the site quietly calling itself over HTTP. If the server, a firewall, basic auth on a staging site, or a security plugin blocks that self call,
wp-cron.php never gets reached and the queue stops.
One task throws a fatal error and jams the line. wp-cron runs due tasks in sequence, so if one of them crashes hard, the tasks behind it can stall. A single broken plugin job can quietly hold up your backups and your emails along with it.
How you usually find out, too late
The classic symptom is a post stuck on “Missed schedule” instead of going live. But the list is longer than that. WooCommerce emails not sending. Subscription renewals not charging. Backup plugins showing a last run date from weeks ago. Abandoned cart reminders that never fire. Transients and caches that never expire and slowly bloat the database. Every one of these runs on wp-cron, and every one of them fails in silence.
By the time any of it reaches you, it has usually been broken for days. That is the real cost. Not that it failed, but that nothing told you it failed.
The reliable setup
The fix most experienced people land on is to stop relying on visitor traffic. You turn off the pseudo cron with define('DISABLE_WP_CRON', true), then add a real system cron entry that calls the
site on a fixed schedule, every five or fifteen minutes, using wp-cron.php or WP-CLI (wp cron event run --due-now). Now the schedule moves on a real clock instead of hoping someone
visits.
This is genuinely better. But notice what it does not solve. A system cron can also stop. A server migration drops the crontab. A path changes. WP-CLI goes missing after an update. You have moved the single point of failure, you have not removed it. Something still has to watch the watcher.
Knowing before the client does
This is the gap WPPulse fills for cron. Instead of trusting that the schedule is running, it checks whether jobs that should have run actually have, and alerts you when one goes overdue. It works the same whether you use the default wp-cron or a real system cron, so the safer setup above does not leave you blind. And when the job catches back up, the alert resolves on its own, so you are not chasing a problem that already fixed itself.
The point is not to replace your cron setup. It is to know the moment it stops, while it is still a five minute fix and not a three week mystery. You can see how the cron monitor works at wp-pulse.app.
A quick self check
If you want to see the state of your own site right now, the fastest way is WP-CLI: wp cron event list shows every scheduled task and when it is next due. If events have a next run time in the
past and keep sitting there, your cron is not firing. No WP-CLI handy? A plugin like WP Crontrol shows the same list inside the admin. Either way, if the backup job was meant to run at 3am and it is still pending
at noon, you have found your problem.