The site is quick almost all the time. Then, every so often, a page hangs for several seconds before anything appears, and the next one is fine again. You cannot reproduce it on demand. The host’s graphs show short spikes at odd moments, and a hosting support agent has raised, without much detail, the possibility of WP-Cron slowing your website.
They may well be right. WordPress has its own built-in scheduler, and the way it is triggered ties background work to visitor traffic. Most of the time that costs very little. On some sites it is the reason a heavy job lands in the middle of a busy hour and takes the server’s attention away from the people actually browsing.
This post covers the speed side: how WP-Cron runs, which tasks make it heavy, how to see what is scheduled, and how moving it to a real server cron takes it off the visitor path. If your problem is the opposite, tasks that never run at all and posts showing “Missed schedule”, our guide to WordPress cron not running deals with that.
How WP-Cron actually runs
A normal server has a clock-driven scheduler that starts jobs at set times whether anyone is visiting or not. WordPress cannot rely on having access to that, so it does something different.
- On page loads, WordPress checks its list of scheduled tasks, which it keeps in the database.
- If something is due, it sends a quick background request from the server to itself, to a file called
wp-cron.php. - That second request loads WordPress again and runs the due tasks.
- A short lock stops several of these runs starting on top of each other.
The visitor’s own page normally does not wait for the tasks to finish; WordPress fires the background request and moves on. So where does the slowdown come from?
Where the speed cost comes from
The tasks compete with visitors for the same server
The background request runs on the same hosting, using the same processor, memory and PHP processes as your visitors. A light task, such as checking for plugin updates, finishes quickly and nobody notices. A heavy one, such as a full backup, a security scan of every file or an import of a large product feed, can occupy a PHP process and a good share of the processor for minutes. On a modest plan, every visitor who arrives in that window waits longer. Our explainer on how PHP workers handle requests shows why one long job can make other pages queue.
The timing is random
Because the trigger is a visitor arriving, tasks run whenever traffic happens to wake them, not at a time you chose. A backup scheduled for “daily” may start at 11 in the morning, right as your newsletter goes out.
Sometimes the visitor does wait
On some servers the background request cannot be made, for example because the server cannot call its own address. A common workaround is a setting called ALTERNATE_WP_CRON, which makes WordPress run the tasks during a visitor’s own page load instead. That visitor then waits for whatever happened to be due. If this constant is set in your wp-config.php, it is worth asking why.
A bloated schedule is loaded on every request
The list of scheduled tasks is stored as a single setting that WordPress loads on every page. Normally it is small. A misbehaving plugin can add thousands of entries, often one-off events that never get cleared. Then every single request, cached pages excepted, carries that extra weight. This overlaps with the wider problem of heavy autoloaded options in WordPress.
Tasks that tend to be heavy
- Full-site backups, especially those that zip files on the server.
- Malware and file-change scans from security plugins.
- Product, stock or price imports from suppliers and marketplaces.
- Broken link checkers that visit every link on every page.
- Bulk image optimisation running through the media library.
- Sitemap or search index rebuilds on large sites.
- WooCommerce’s queue of background actions for emails, webhooks and syncing, which grows quickly on a busy store.
- Newsletter plugins sending mail in batches from the server.
None of these are wrong to have. They are just better run at a time you choose than at a time a visitor happens to trigger.
How to see what is scheduled
With a plugin
WP Crontrol is the usual choice. Once installed, Tools, then Cron Events, lists every scheduled task, which plugin hook it belongs to, how often it repeats and when it is next due. Look for:
- Tasks set to run very frequently, such as every minute, that do not need to.
- Several heavy tasks bunched at the same time.
- Events belonging to plugins you have already removed.
- A very long list of near-identical one-off events from one plugin.
With WP-CLI
If your host gives you a command line, wp cron event list shows the same information without installing anything.
In WooCommerce
Stores have a second queue. WooCommerce, then Status, then Scheduled Actions shows pending, completed and failed actions. A large number of past-due pending actions means the store’s background work is falling behind and running in big bursts when it does catch up.
In Site Health
Tools, then Site Health, reports when a scheduled event is late or has failed, and runs a loopback test that tells you whether the server can make the background request at all.
Is WP-Cron slowing your website? Reading the evidence
The pattern that points at WP-Cron rather than at visitors or the page:
- Slow requests come in short clusters, not steadily through busy hours.
- The host’s CPU or process graph shows spikes that do not match visitor numbers in analytics.
- The access log shows requests to
wp-cron.phparound the slow moments. - The plugin list in WP Crontrol has a heavy task whose interval matches the rhythm of the slowdowns.
If two or three of those line up, you have your answer.
Moving WP-Cron off visitor traffic
The fix has two parts that must go together. First, add the constant DISABLE_WP_CRON with a value of true to your wp-config.php file, so that page loads no longer trigger the schedule. Second, add a scheduled job in the hosting control panel that runs the WordPress queue at a regular interval.
That job can either request wp-cron.php over the web, or, where WP-CLI is available, run wp cron event run --due-now from the site’s folder. The command-line version avoids a web request and is not affected by caching or security rules in front of the site.
How often should it run? Match it to the most time-sensitive task you have. A brochure site is fine with every quarter of an hour. A store sending order emails and syncing stock may want every few minutes. Do not leave the first part done without the second, or nothing will run at all, which is exactly the failure described in the cron-not-running guide linked above.
The official WordPress developer documentation on cron describes the scheduler and the server cron approach if you want the technical background.
Making the tasks themselves lighter
A real cron controls when things run. It does not make heavy jobs lighter. A few changes help with that:
- Move backups off the server. A backup service or host-level backup that works outside WordPress takes the zipping and uploading away from PHP entirely.
- Spread heavy jobs across quiet hours instead of letting them pile into the same slot.
- Reduce frequency where it does not matter. A link checker does not need to run hourly. A security scan once a day is often enough for a small site.
- Remove orphaned events left behind by plugins you deleted, and question any plugin that schedules thousands of one-off tasks.
- On a store, clear old completed actions and investigate failed ones, since a queue that keeps failing keeps retrying.
Scheduled work is one of the hidden loads covered in our group guide on what the hosting decides about speed, and one of many small fixes in our guide on how to make a website load faster.
Frequently asked questions
Does disabling WP-Cron make my site faster on its own?
Only if you also add a server cron job, and even then the gain comes from control rather than from less work. The same tasks still run on the same server, but at steady intervals you choose, away from the visitor path. Disabling it without a replacement simply stops scheduled tasks, which breaks backups, emails and scheduled posts.
Will a page cache stop WP-Cron from running?
It can reduce how often it runs. When a cached page is served without loading WordPress, the schedule is not checked on that visit. On a well-cached site with little uncached traffic, tasks may then run late. That is another good reason to use a real server cron on cached sites.
How do I know which plugin a scheduled event belongs to?
The event’s hook name usually includes the plugin’s name or a short prefix it uses. WP Crontrol also shows the function each hook calls where it can. If the name is unclear, searching the hook name together with the word WordPress usually identifies the plugin quickly.
Is it safe to delete scheduled events I do not recognise?
Not without checking. An unfamiliar name may belong to your theme, a form plugin or the store. Deleting a recurring event from an active plugin usually just causes it to be scheduled again, while deleting one that matters can stop a feature quietly. Confirm which plugin it belongs to and that the plugin is gone before removing it.
A clean schedule with the random slowdowns still happening means the cause sits somewhere else, on the server or in the page. That is where our speed optimisation work picks up: an audit that includes server response time and the database, a fix list in order of impact, and a re-test once the changes you approved are in.
Next in this series: Autoloaded Options in WordPress: Find and Trim Them