WP-Cron is fine until a site starts depending on timing. Scheduled posts that go live late, renewal emails that drift, imports that only run after a random visit, or client complaints that no one can reproduce are usually not WordPress bugs. They are symptoms of using a traffic-triggered scheduler for work that the business now treats as operationally important.
For most serious WordPress sites, the practical move is not to replace WordPress's scheduling system. It is to replace the trigger. Let WordPress keep the event queue, but let the server's real scheduler wake it up on a predictable interval. That gives owners, operations leads, and agency teams a setup that is easier to trust, easier to test, and easier to support.
What WP-Cron does well, and where it breaks down
WordPress core and plugins use WP-Cron for update checks, scheduled publishing, cleanup, and other background tasks. The important design detail is that WP-Cron checks for due events on page load. It is not a continuously running system process. If no one visits the site, nothing fires at the intended time.
That does not mean WP-Cron is useless. One useful property is that overdue jobs stay in the queue and run on the next opportunity. If eventually is good enough, the default behavior may be completely acceptable. If exact timing matters, it is the wrong reliability model. On some stacks there is a second problem as well: the default spawning path depends on WordPress being able to make an HTTP request back to itself. If loopback requests are blocked or flaky, tasks can fail even on busy sites.
When to keep the default setup
You do not need to force server cron onto every site. Keeping standard WP-Cron is usually reasonable when:
- The site is mostly informational and a delay of several minutes or longer has no business impact.
- No revenue, fulfillment, or client-facing workflow depends on background jobs running on time.
- You are on hosting that does not expose a reliable scheduler and the operational overhead is not justified.
In other words, default WP-Cron is not wrong. It is just a best-effort system, and best-effort is only acceptable when the business risk is low.
When server cron is the better choice
Move to server cron when missed or delayed tasks create real cost. Common cases include campaign-driven publishing, ecommerce or membership workflows, feed imports, third-party sync jobs, cache warming, cleanup routines, and agency-managed sites where support time is expensive.
A simple rule helps here: if your team has ever asked, "Did cron actually run?", the site is probably mature enough for a real scheduler.
The safe way to switch
The official WordPress guidance is straightforward: disable page-load cron spawning and have the operating system call WordPress on a schedule instead. The required configuration change is:
define( 'DISABLE_WP_CRON', true );Add that to wp-config.php only after the replacement job is ready. If you disable WP-Cron first and forget the second step, scheduled events will stop running.
Option 1: Trigger wp-cron.php over HTTP
This stays close to the WordPress handbook and works well when the site is publicly reachable from the server with no authentication, firewall, proxy, or CDN rule getting in the way.
*/5 * * * * wget --delete-after --quiet https://example.com/wp-cron.php >/dev/null 2>&1This is easy to understand and often good enough for small to mid-sized business sites.
Option 2: Use WP-CLI to run due events
For managed servers, WP-CLI is often the cleaner operational choice because it avoids the web layer and gives you a command your team can run, log, and troubleshoot directly.
*/5 * * * * /usr/local/bin/wp cron event run --due-now --path=/var/www/example.com >/dev/null 2>&1If you run multisite, add --url=https://example.com to target the correct site. If the cron user does not have wp in its PATH, use the full binary path as shown above.
For frequency, five minutes is a sensible default. One minute can make sense when order processing, renewals, or time-sensitive automations truly justify it. Fifteen minutes is often enough for a simple marketing site. Choose the interval based on the business cost of delay, not habit.
How to test it properly
This is where a lot of articles blur an important detail. wp cron test is useful before the switch, not after it. WP-CLI's test command checks WordPress's built-in cron spawning path and will error if DISABLE_WP_CRON is set to true. That makes it a good diagnostic for default WP-Cron and loopback issues, but not the right verification step once server cron takes over.
After the change, use practical checks that validate the replacement path instead:
wp cron event list --fields=hook,next_run_gmt,next_run_relative,recurrence
wp cron event run --due-nowThen manually run the exact scheduler command as the same system user that cron uses. If you chose the HTTP method, call wp-cron.php from the server and confirm nothing in the web stack blocks it. If you chose WP-CLI, confirm the command can see the correct WordPress path, PHP binary, and file permissions. What you want to see is simple: due events execute, the queue advances, and time-sensitive jobs stop drifting.
Common mistakes that create noisy support work
- Disabling WP-Cron without putting the replacement job in place first.
- Running cron as a user that cannot access the right files, binaries, or environment.
- Using the HTTP method on a site protected by basic auth, strict firewall rules, or reverse-proxy logic.
- Assuming a more frequent cron interval will fix a plugin task that is actually slow, broken, or badly designed.
- Leaving multiple schedulers active and making diagnosis harder than it needs to be.
For business sites, replacing traffic-triggered cron with server cron is usually a small infrastructure change with outsized operational value. It does not make WordPress more complex. It makes background work more predictable.
If you need someone to audit how scheduled work runs across WordPress, plugins, hosting, and handoff documentation, Greg can help put a cleaner setup in place without turning a simple reliability fix into a bigger rebuild.
Need help with this kind of work?
Talk to Greg if you want a cleaner WordPress cron setup that your team can trust and support. Get in touch with Greg.
Sources
- Cron – Plugin Handbook | Developer.WordPress.org
- Hooking WP-Cron Into the System Task Scheduler – Plugin Handbook | Developer.WordPress.org
- wp cron event run – WP-CLI Command | Developer.WordPress.org
- wp cron event list – WP-CLI Command | Developer.WordPress.org
- wp cron test – WP-CLI Command | Developer.WordPress.org