WordPress has its own task scheduler, WP-Cron, and most people never think about it until scheduled posts publish late or a busy site’s CPU spikes for no obvious reason. The root cause is the same in both cases: WP-Cron isn’t a real cron job. It’s faked with page loads — and that assumption breaks at both ends of the traffic scale.
Despite the name, WP-Cron is named after the Unix cron scheduler, not “chronograph” — and the “pseudo” part matters. A real cron job is fired by the operating system’s clock at exact times, whether or not anyone is using the machine. WP-Cron has no clock of its own; it hitches a ride on visitor traffic.
Trigger = page loads. Low traffic: tasks run late or never (no visitor). High traffic: fires on nearly every request — wasted CPU.
Trigger = the OS clock, on a fixed interval (e.g. every 15 min), independent of traffic. Punctual on quiet sites, no per-visit overhead.
Table of Contents
What WP-Cron actually is
WP-Cron is WordPress’s scheduling system. It runs the time-based jobs the platform and your plugins depend on:
- publishing scheduled posts at their set time,
- checking for core, plugin and theme updates,
- running recurring plugin and theme tasks (backups, syncs, cache warming, email digests),
- housekeeping like clearing transients.
The catch is how it fires. On each page load, WordPress checks whether any scheduled task is due and, if so, runs it in the background. There’s no separate timer — the page load is the timer.
WP-Cron has no clock. A page load is its only heartbeat — which is exactly why it’s unreliable at both traffic extremes.
Why page-load triggering breaks — at both ends
Tying the scheduler to traffic creates two opposite problems.
On a low-traffic site, tasks run late or never. If nobody visits between 2pm and 6pm, a task scheduled for 2pm doesn’t run until the next visitor arrives. Scheduled posts publish late, updates lag, and time-sensitive jobs drift. The scheduler is only as punctual as your traffic.
On a high-traffic site, it’s pure overhead. Now the opposite happens: WP-Cron fires on nearly every request. Each check spends PHP CPU and memory deciding whether anything is due, and it adds work to page loads that should be fast. At scale, that overhead is measurable — one more reason a busy site feels sluggish. It’s a classic entry in any WordPress speed audit.
The scheduler is only as punctual as your traffic — and only as cheap as your traffic is light.
The fix: disable WP-Cron and use a real system cron
The standard fix — documented by WordPress itself — is to stop WordPress from triggering cron on page loads and instead call it on a fixed schedule from the server’s real cron. Two steps:
1. Turn off the page-load trigger in wp-config.php, above the “stop editing” line:
define( 'DISABLE_WP_CRON', true );Code language: PHP (php)
2. Call WP-Cron on a schedule from your server’s crontab (or your host’s control-panel cron). Every 15 minutes is a sensible default:
*/15 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1Code language: Bash (bash)
Now the scheduler runs on a clock, independent of traffic: quiet sites stay punctual, and busy sites stop paying the per-request tax. On WP-CLI hosts you can call wp cron event run --due-now from cron instead of hitting the URL, which avoids the extra HTTP request entirely.
If you’d rather not touch the server
Editing wp-config.php and a crontab is the cleanest fix, but not the only one:
- A cron-manager plugin gives you a UI to see every scheduled event, spot runaway or duplicate jobs, and change frequencies — useful for diagnosing what’s scheduled even if you keep the default trigger. Since it’s one focused job, it’s a fair candidate for a code snippet rather than a plugin if you only need the scheduling change.
- Managed WordPress hosting typically disables WP-Cron for you and wires a real system cron at the platform level, so cron “just works” without you configuring anything.
The short version
WP-Cron is WordPress’s task scheduler, but it’s fired by page loads rather than a clock, so it misbehaves at both traffic extremes: scheduled posts and jobs run late on quiet sites (no visitor to trigger them) and it wastes CPU on busy ones (firing on nearly every request). The reliable fix is to set define( 'DISABLE_WP_CRON', true ); in wp-config.php and call wp-cron.php from a real server cron on a fixed interval such as every 15 minutes — punctual on quiet sites, no per-visit overhead on busy ones. A cron-manager plugin helps you see what’s scheduled, and managed hosts usually set this up for you.
Frequently Asked Questions
Is WP-Cron a real cron job?
No. A real cron job is fired by the operating system’s clock at set times regardless of activity. WP-Cron is a “pseudo-cron” triggered by WordPress page loads, so it only runs when someone visits your site — which is why it’s unreliable on low-traffic sites and wasteful on high-traffic ones.
Why do my scheduled posts publish late?
Almost always because WP-Cron didn’t fire on time. With no visitor between the scheduled time and later, nothing triggered the scheduler, so the post waited until the next page load. Running WP-Cron from a real system cron on a fixed interval fixes this.
Does disabling WP-Cron break scheduled tasks?
No — as long as you replace it. Setting DISABLE_WP_CRON only turns off the page-load trigger; you then call wp-cron.php from a server cron (for example every 15 minutes) so the same tasks run on a reliable schedule instead of a traffic-dependent one.
How often should the server cron run WP-Cron?
Every 15 minutes suits most sites — frequent enough that scheduled posts and jobs feel timely, infrequent enough to add negligible load. If you rely on minute-level precision, run it every 5 minutes; if you have very few scheduled tasks, hourly is fine.
Will this speed up my site?
On a high-traffic site, yes, modestly — you remove the cron check from nearly every page load. It won’t transform a slow site on its own, but it’s a clean win and a standard step once you’ve handled the bigger bottlenecks in a speed audit.