If a WordPress post scheduled for 9:00am doesn’t actually go live until 9:47am, that’s not a bug — it’s exactly how wp-cron is designed to work, and it’s a limitation worth understanding directly rather than treating as an occasional glitch. WordPress’s default scheduler fires tasks on the next page request that happens to arrive after the scheduled time, not on a fixed clock — if nobody visits the site for hours, nothing scheduled runs during that window, no matter what time it was supposed to fire.
Why This Happens
wp-cron has no background daemon of its own — it piggybacks entirely on real visitor traffic to check whether anything’s due to run. A real system cron daemon, by contrast, wakes up on a fixed interval (typically every minute) and runs whatever’s due regardless of whether anyone’s actively using the site at that moment. On a low-traffic site, or one that happens to have a quiet period right around a scheduled event, that gap between “scheduled time” and “actually ran” can stretch well past what anyone would consider acceptable.
What This Actually Affects
This isn’t limited to scheduled posts — it’s every task WordPress or a plugin schedules through the cron API: plugin update checks, scheduled email sends, backup jobs, cache-clearing tasks, and any custom scheduled functionality a theme or plugin adds. A site that seems to intermittently “forget” to do something on time is very often just wp-cron waiting for a visitor who hasn’t shown up yet.
The Real Fix
WordPress’s own Plugin Handbook recommends disabling the traffic-dependent default and replacing it with a real server-level cron job:
- Add
define('DISABLE_WP_CRON', true);towp-config.php— this stops WordPress from trying to fire cron on page loads at all. - Set up a real system cron job that hits
wp-cron.phpdirectly on a fixed schedule — every 5 to 15 minutes is the commonly recommended interval, balancing timeliness against unnecessary load. - Confirm the cron job is actually running after setup — a misconfigured real cron job that silently fails is worse than the default, since there’s no visitor-triggered fallback anymore once
DISABLE_WP_CRONis set.
If server-level cron access isn’t available (common on some shared hosting setups) or isn’t something you want to manage, a third-party cron service that pings wp-cron.php on a schedule from outside the server accomplishes the same thing without needing SSH access.
How to Check If This Is Actually Your Problem
A dedicated cron-inspection plugin can show you exactly which scheduled events exist and whether any are marked as having missed their schedule — that’s the direct way to confirm wp-cron reliability is the actual cause before changing server configuration, rather than guessing based on symptoms alone.
This is the same underlying category of “something silently isn’t running when it should” issue we cover from a different angle in Finding N+1 Queries on WordPress with Query Monitor. Want your site’s scheduled tasks audited and fixed? Get in touch.
Frequently Asked Questions
Does this affect every WordPress site, or only low-traffic ones?
It’s a bigger practical problem on low-traffic sites since long visitor gaps are more common, but any site can experience a delay during a genuinely quiet period — the mechanism is the same regardless of overall traffic volume.
Is disabling wp-cron risky?
Only if you don’t replace it with something — disabling the default without setting up a real server cron job means scheduled tasks stop running entirely, which is worse than the original delay problem.
How do I know what interval to use for the real cron job?
Every 5 to 15 minutes is the commonly recommended range — frequent enough to keep scheduled tasks close to on-time, without adding unnecessary server load from checking too often.
Featured image: original illustration.
