Skip to content
WordPress

How to Disable WP-Cron in WordPress

· · 11 min read
How to Disable WP-Cron in WordPress

WordPress ships with its own task scheduler called WP-Cron, and most site owners never think about it until something goes wrong. It handles publishing scheduled posts, checking for plugin and theme updates, sending scheduled emails, and running maintenance jobs that plugins register in the background. The catch is in how it actually runs: WP-Cron doesn’t run on a timer the way a real cron job does. It fires on page load, triggered by an actual visitor hitting your site.

That design choice made sense in 2003 when WordPress was mostly running on shared hosting without reliable access to system-level cron. It causes two separate problems today. A busy site fires wp-cron.php on nearly every request, which means WordPress checks “is anything due to run?” dozens or hundreds of times a minute even when nothing is scheduled. A quiet site has the opposite problem: if nobody visits between 2 a.m. and 6 a.m., nothing scheduled for that window fires until the next visitor happens to land on the page.

This guide walks through disabling WP-Cron properly, replacing it with a real system cron job, verifying it actually works, and fixing the handful of ways this setup commonly breaks.

What WP-Cron Actually Does Behind the Scenes

Every time a browser requests a page from your WordPress site, one of the last things that happens before the response is sent is a check against the wp_options table for a value called cron. That value is a serialized array of every scheduled event on the site, along with the timestamp each one is due to run. If anything is past due, WordPress spawns a separate, non-blocking HTTP request to wp-cron.php to execute it. The page the visitor requested finishes loading normally; the cron check happens in parallel and doesn’t hold up the response, at least in theory.

In practice, that non-blocking request isn’t always as free as it sounds. On hosts with limited PHP workers, that extra request competes for the same resources as everything else on the box. If your scheduled jobs are heavy, an XML sitemap regeneration, a full-site backup trigger, a bulk email send through a marketing plugin, that competition becomes visible as slower page loads for real visitors.

Signs You Should Disable WP-Cron

A handful of patterns show up repeatedly in sites that benefit from switching to a real cron job.

Traffic spikes correlate with slowdowns that don’t match the actual load. If your hosting dashboard shows CPU or memory spiking well beyond what the visitor count would explain, wp-cron.php firing on every request is a common culprit, especially if you’re running WooCommerce, a membership plugin, or anything with heavy scheduled tasks.

Scheduled posts publish late, or don’t publish at all. This is the low-traffic failure mode. A blog that gets a handful of visits overnight might not trigger wp-cron.php for hours, so a post scheduled for 6 a.m. might not actually go live until the first visitor arrives well after that.

Backup or import jobs time out or run inconsistently. Resource-heavy scheduled tasks, full-site backups, large CSV imports, bulk transactional emails, tend to be the ones that suffer most from WP-Cron’s request-triggered model, because they need a predictable execution window rather than a random one tied to whenever a visitor shows up.

None of these problems are guaranteed to show up on every site. A low-traffic personal blog with no heavy plugins may never notice a difference either way. A store running WooCommerce Subscriptions, an email automation plugin, and a daily backup job is a much stronger candidate.

Step 1: Back Up Before Touching Anything

Before editing wp-config.php, take a full backup, or at minimum a copy of that one file. It’s a small edit, but wp-config.php controls database credentials and core constants, and a typo here can take the whole site down. UpdraftPlus, BlogVault, or your host’s built-in backup tool handles this in a couple of clicks. If your host offers a one-click restore point before making config changes, use it.

Step 2: Disable WP-Cron in wp-config.php

Connect to your site via FTP (FileZilla works fine) or your host’s file manager, and open wp-config.php in the root directory. Add this line before the comment that reads /* That’s all, stop editing! Happy blogging. */:

define('DISABLE_WP_CRON', true);

This single constant tells WordPress to stop spawning the wp-cron.php request on page load entirely. It does not delete any scheduled events; they stay queued in the database. They just won’t fire until something else triggers wp-cron.php, which is exactly what the next step sets up.

One detail worth knowing: some managed hosts, Kinsta and WP Engine among them, already disable WP-Cron by default and run their own system-level cron in its place, often every 15 minutes. Check your host’s documentation before assuming you need to do this manually; adding the constant yourself on a host that already handles it isn’t harmful, but it’s redundant.

Step 3: Set Up a Real Server Cron Job

With WP-Cron disabled, you need something external hitting wp-cron.php on a schedule. Most shared and managed hosts expose a cron job interface through cPanel or Plesk.

Using cPanel

Log into cPanel and find Cron Jobs under the Advanced section. Add a new job with this command, swapping in your actual domain:

wget -q -O /dev/null https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Some hosts prefer curl over wget:

curl https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Either works. The important part is redirecting output to /dev/null so cPanel doesn’t email you every 15 minutes with the response body.

Setting the Schedule

Every 15 minutes is the standard interval for most sites: minute field */15, everything else set to *. A high-frequency news site or a store processing time-sensitive orders might drop that to every 5 minutes. A low-traffic brochure site can usually get away with hourly. There’s no single right answer here; it depends on how time-sensitive your scheduled events actually are.

WP-CLI Alternative

If your host gives you SSH access and WP-CLI is installed, you can run cron events directly instead of hitting wp-cron.php over HTTP:

wp cron event run --due-now

Set that as the cron command instead of the wget/curl approach. It skips the HTTP round-trip entirely, which is marginally faster and avoids any issue with wp-cron.php being blocked by a firewall or security plugin. The tradeoff is that it requires shell access, which shared hosting sometimes restricts.

Alternative: ALTERNATE_WP_CRON Instead of a Server Cron Job

Not every host offers a cron job interface. Some cheap shared plans genuinely don’t expose one, and asking support to add one isn’t always an option. For that situation, WordPress has a middle-ground constant that doesn’t require touching a server-level scheduler at all:

define('ALTERNATE_WP_CRON', true);

This changes how the cron check works rather than disabling it. Instead of firing a separate background HTTP request, WordPress runs the cron check as a redirect loop within the same page load, which avoids the loopback request problem some hosts have (where a firewall or local DNS setup blocks the site from calling itself). It’s a workaround, not a fix, and it still ties cron execution to visitor traffic the same way the default behavior does. Use it only if a real server cron job genuinely isn’t available, and switch to one the moment it is.

Using an External Monitor as a Cron Trigger

A less common but workable option is pointing an uptime monitoring service at wp-cron.php directly. Services like UptimeRobot or Pingdom, which most sites already run for downtime alerts, can be configured to hit a specific URL on an interval as short as one minute on paid tiers. Setting one of these checks to poll https://yourdomain.com/wp-cron.php?doing_wp_cron every five minutes accomplishes the same thing as a cPanel cron job, with the added benefit of running from outside your own server, so a server-level outage doesn’t also kill your cron trigger. It’s not a replacement for a real cron job on a site with anything time-critical, but it’s a reasonable stopgap or a redundancy layer on top of your primary cron setup.

Cron Behavior on Multisite Networks

WordPress Multisite complicates this slightly because each subsite in the network has its own independent cron queue, but wp-cron.php only fires for the specific site a visitor lands on. A network with one high-traffic flagship site and a dozen quiet subsites can end up with cron events piling up on the quiet ones indefinitely, since nobody’s visiting those to trigger anything. The fix is the same server cron job described above, but the cron command needs to hit each subsite’s wp-cron.php individually, or you can use a plugin like WP Crontrol network-wide to audit which subsites have overdue events and script a loop that pings all of them on the same schedule.

Step 4: Verify It’s Actually Working

Don’t assume the cron job is firing correctly just because you set it up. Install WP Crontrol from the WordPress plugin directory, then go to Tools > Cron Events in your dashboard. You’ll see every scheduled hook, when it’s next due, and how it’s scheduled to recur. If events are consistently overdue by more than your cron interval, something upstream isn’t firing.

A manual test is worth running once: SSH in and execute the wget or curl command by hand, or trigger it through your hosting terminal. If it returns cleanly with no errors, the mechanism itself works and any remaining issue is likely on the scheduling side (a typo in the cron syntax, wrong domain, wrong path).

Common Problems and Fixes

The cron job runs but nothing happens

Double-check the URL in the cron command matches your site exactly, including www versus non-www and http versus https. A mismatched protocol or a redirect chain can silently swallow the request. Also confirm DISABLE_WP_CRON is actually set to true and not accidentally left as a string or duplicated with conflicting values elsewhere in wp-config.php.

Scheduled posts still publish late

This usually means the server cron isn’t actually reaching wp-cron.php. Check whether a firewall, security plugin, or .htaccess rule is blocking direct access to that file. Wordfence and some other security plugins can flag repeated wp-cron.php requests as suspicious traffic and rate-limit them, which defeats the purpose of a frequent cron job.

Cron events pile up and never clear

If WP Crontrol shows a growing list of events stuck in the past, it often points to a plugin that scheduled something but never properly unschedules it, sometimes after being deactivated without cleanup. You can manually delete stuck events from the WP Crontrol interface, but the underlying fix is identifying which plugin is responsible and checking whether an update resolves it.

High server load even after switching to real cron

If load didn’t improve, the bottleneck likely isn’t WP-Cron’s triggering mechanism at all; it’s the tasks themselves being heavy. Reducing cron frequency doesn’t help if a single scheduled job is doing an expensive database query or processing a large file. Use Query Monitor to see what’s actually running during a cron execution and optimize from there.

Tools Worth Knowing

A few tools come up repeatedly in cron troubleshooting beyond what’s already mentioned above.

WP Crontrol remains the standard for inspecting and editing cron events directly from the dashboard, including deleting stuck ones, and it’s the fastest way to see what’s actually scheduled without touching the database.

Query Monitor shows you exactly what queries and hooks run on a given request, including cron requests, which makes it useful for tracking down which specific scheduled task is slow.

EasyCron is a third-party service worth considering if your host doesn’t offer cron jobs at all, or if you want cron pings coming from outside your own server for redundancy.

If you’re not comfortable with SSH or cPanel’s cron interface, WP-CLI commands can also be scheduled through some hosting panels directly, and a few managed WordPress hosts now offer a toggle for “alternate cron” that handles this whole setup without any manual configuration at all.

A Quick Pre-Launch Checklist

Before considering this done, run through these five checks on a staging copy first if you have one available.

  1. Confirm the site loads normally after adding DISABLE_WP_CRON to wp-config.php. A typo in this file can produce a white screen.
  2. Trigger the cron command manually once by hand and confirm it returns without an error.
  3. Wait through at least two full cron intervals and check WP Crontrol to confirm events aren’t drifting later over time.
  4. Schedule a test post five minutes out and confirm it actually publishes on time rather than waiting for a visitor.
  5. Check your host’s error log for any repeated failed requests to wp-cron.php, which usually points to a firewall rule worth adjusting.

Frequently Asked Questions

Will disabling WP-Cron break scheduled posts?

No, as long as you replace it with a working server cron job. Scheduled posts, plugin update checks, and any other cron-dependent feature still work; they just run on the interval your server cron defines instead of being tied to visitor traffic.

How often should the cron job run?

Every 15 minutes covers most sites without adding meaningful server load. Time-sensitive stores or news sites sometimes drop to 5 minutes. There’s rarely a good reason to go below that; anything more frequent adds overhead without a proportional benefit for most use cases.

Do I still need this on managed WordPress hosting?

Often not. Kinsta, WP Engine, and several other managed hosts disable WP-Cron by default and run their own system cron automatically. Check your host’s knowledge base before setting this up manually to avoid running two competing cron mechanisms.

What happens to events that were already overdue when I disabled WP-Cron?

They stay queued and fire the next time the cron mechanism runs, whether that’s your new server cron job or, if you haven’t set one up yet, the next page visit (since disabling the constant alone doesn’t stop wp-cron.php from working if something else calls it directly).

Can a caching plugin interfere with cron?

Full-page caching can sometimes serve a cached response before WordPress ever checks the cron table, which is part of why request-triggered cron is unreliable on cached sites in the first place. This is actually one of the stronger arguments for switching to a server-level cron job rather than relying on visitor traffic at all.

What’s the difference between DISABLE_WP_CRON and ALTERNATE_WP_CRON?

DISABLE_WP_CRON stops WordPress’s built-in trigger entirely and requires an external source, typically a server cron job, to call wp-cron.php on a schedule. ALTERNATE_WP_CRON keeps the visitor-triggered model but changes the technical mechanism to a redirect instead of a background HTTP request, mainly to work around loopback connection issues on certain hosts. They solve different problems and generally shouldn’t be used together.

Is it safe to run the cron job every minute instead of every 15?

Technically yes, but it rarely helps. Most scheduled WordPress tasks aren’t time-critical to the minute, and hitting wp-cron.php that frequently adds constant background load for very little practical gain. Reserve minute-level frequency for specific cases like time-sensitive booking systems or flash sale countdowns where a few minutes of delay genuinely matters.


Interesting Reads

10 Best AI Ask Research Tools Today

What’s a Bold New Font Style Used in WordPress?

10 Best Software for Electronic Signature on Documents