DISABLE_WP_CRON = true does not seal the wp-cron.php endpoint; it only stops WordPress from firing its own loopback request. The file stays reachable from the web, so anyone can still hit it and force a full WordPress bootstrap.

That hidden entry point can waste CPU, memory and PHP workers, especially on busy sites. If you thought you had turned the door off, you haven’t—yet.

Why the setting is often misunderstood

When WordPress runs a scheduled task it first tries a quick HTTP request to its own wp-cron.php file. Setting DISABLE_WP_CRON to true tells the core to skip that internal request. The core does not change the web-server configuration, nor does it add any authentication layer to wp-cron.php. The script remains a public URL that returns a 200 status even if the PHP process aborts early.

An attacker who discovers the URL can ping it repeatedly, causing WordPress to load all plugins, themes and the database each time. On a shared host or a site with limited PHP workers, that single endpoint can become a denial-of-service vector.

What really needs to be done

To move scheduled work to a system-level scheduler (cron, systemd-timer, etc.) and close the public door, follow these five steps.

1. Disable the internal loopback

Add the line

define( 'DISABLE_WP_CRON', true );

to wp-config.php. This stops WordPress from trying its own HTTP request, but it does not stop external calls.

2. Block wp-cron.php at the web-server

With Nginx, for example, insert a location block that returns 403 Forbidden:

location = /wp-cron.php {
    return 403;
}

The server now rejects the request before PHP even starts, eliminating the bootstrap cost.

3. Add a mu-plugin as a safety net

Create a must-use plugin (placed in wp-content/mu-plugins) that logs any request reaching wp-cron.php and exits with a 403. This catches requests that somehow bypass the server rule—perhaps through a different hostname or a CDN edge rule.

4. Suppress Action Scheduler async calls

Many plugins use the Action Scheduler library, which can spawn its own loopback requests. Hook into action_scheduler_queue_runner and return early for non-CLI requests, preventing the library from trying to open its own doors.

5. Unhook the queue runner from the WP-Cron hook

Remove the default Action Scheduler queue runner that is attached to the wp cron hook. This ensures the queue only runs when you explicitly trigger it from the command line.

Running jobs the right way

With the public endpoint sealed, use the system scheduler to invoke WordPress once per minute (or whatever cadence you need) via WP-CLI:

wp cron event run --due-now

That single command processes core cron events and the Action Scheduler queue in a controlled environment, using the same PHP process you would use for any other CLI task.

Benefits you can measure

  • Security – No unauthenticated user can start heavy background work.
  • Performance – PHP workers stay available for real visitors; memory spikes from stray cron hits disappear.
  • Reliability – Scheduling becomes proactive; you know exactly when a job runs because it’s driven by the system’s cron, not by a visitor’s page load.

What to watch after the change

Do not rely on the HTTP status code of wp-cron.php; it may still return 200 even when blocked by PHP. Instead:

  • Monitor the Action Scheduler queue size. A growing queue often signals missed runs.
  • Check server logs for “403” entries from the wp-cron.php location block.
  • Observe PHP-FPM or FastCGI process counts during peak traffic to confirm the load has dropped.

A note of caution

Some administrators keep DISABLE_WP_CRON false because they rely on low-traffic sites to trigger cron naturally. The approach above removes that reliance entirely, but it does add a maintenance step: you must ensure the system scheduler runs reliably. If the server’s cron daemon fails, scheduled jobs stop. Pair the setup with monitoring of the system cron service to avoid that pitfall.

Bottom line: setting DISABLE_WP_CRON to true only stops WordPress from pinging itself; it does not close the public wp-cron.php endpoint. Block the file at the web-server, add a mu-plugin fallback, and route all scheduled work through a system scheduler via WP-CLI. Doing so secures the site, reduces unnecessary PHP work, and gives you precise control over when background tasks execute.