Disable WP-Cron to Improve Performance

8 min read Auf Deutsch lesen

Anyone running WordPress under real conditions can’t avoid WP-Cron – it drives updates, backups and scheduled posts. The problem: it’s based on a trick. Instead of a real system-side cron job, WordPress hooks into every page load and checks there whether a task is due. On high-traffic sites this creates measurable extra load; on low-traffic sites, tasks simply get skipped. This post explains how WP-Cron works internally, when it becomes a problem, how to disable it cleanly and replace it with a real cron job – including verification and common mistakes.

How WP-Cron Works Internally

WordPress attaches a callback to the init hook on every page load. There, the wp_cron() function internally calls spawn_cron() – provided an event is due at all. spawn_cron() sets a transient called doing_cron as a lock with a lifetime of 60 seconds, then sends a non-blocking HTTP request to its own wp-cron.php. That file processes all due events in sequence.

The pattern is clever because it works without cron access on the server – exactly the scenario on cheap shared hosting. The catch is in the detail: every page load runs the full check, even when no event is due. And under load, several wp-cron.php requests can be in flight at the same time within a 60-second window, because the lock only prevents another spawn_cron(), not calls that go directly to the file.

What exactly sits in your WP-Cron is shown by the WP Crontrol plugin. Typical events are:

  • Checking for plugin, theme and core updates
  • Publishing scheduled posts
  • Creating backups (UpdraftPlus, BackWPup, etc.)
  • Optimising database tables
  • Sending emails and processing queues

What actually runs depends on your plugins. Every plugin that needs regular background work registers its own events.

When WP-Cron Becomes a Problem

On high traffic: several hundred simultaneous visitors mean several hundred init calls per second. Even if spawn_cron() is throttled by the transient, the check logic adds up on every request. On top of that, some plugins register very short intervals – say every five minutes – which increases the trigger frequency. The result: superfluous PHP processes that tie up server resources.

On low traffic: if a site has barely any visitors at night, a backup scheduled for 3:00 a.m. can fail to run entirely – because nobody visits the site and triggers the cron. WP Crontrol then shows events with an overdue run time that keep piling up.

Recognisable symptoms: scheduled posts appear late or not at all. Transactional emails arrive late. Plugin update checks don’t happen daily. Backup plugins like UpdraftPlus report overdue runs.

Step by Step: Disabling WP-Cron

1. Back Up wp-config.php

Before we change anything: make a copy of wp-config.php. A typo in this file makes the entire WordPress installation unreachable.

2. Set DISABLE_WP_CRON

Open wp-config.php in the root directory of your WordPress installation. Find this line:

/* That's all, stop editing! Happy publishing. */

Insert the following immediately before it:

// WP-Cron disabled – replaced by a real server cron job
define( 'DISABLE_WP_CRON', true );

From this moment on, no page load triggers spawn_cron() anymore. WP-Cron events stay registered in the database – they just no longer run automatically. So move straight on to step 3.

3. Set Up a Real Cron Job

Option A: cPanel or Plesk

In cPanel you’ll find a form under “Cron Jobs”. Set the interval to */5 * * * * (every five minutes), command:

/usr/bin/php /absolute/path/to/wordpress-installation/wp-cron.php >/dev/null 2>&1

You get the absolute path in your host’s file manager or via SSH with pwd in the WordPress directory. IONOS, Strato and All-Inkl. offer similar interfaces with dropdown intervals.

Option B: SSH and crontab

Connect via SSH, open the crontab editor with crontab -e and add one of the following lines:

# Recommended: call PHP directly – no HTTP overhead, no curl/wget needed
*/5 * * * * /usr/bin/php /var/www/html/wp-cron.php >/dev/null 2>&1

# Alternative: curl – useful when the path is unknown or SSL should be checked
*/5 * * * * /usr/bin/curl -s 'https://domain.tld/wp-cron.php?doing_wp_cron' > /dev/null 2>&1

# Alternative: wget – for older server setups
*/5 * * * * /usr/bin/wget -q -O /dev/null 'https://domain.tld/wp-cron.php?doing_wp_cron' 2>&1

To explain: */5 * * * * means “every fifth minute, every hour, every day, every month, every weekday”. The suffix >/dev/null 2>&1 discards all output, so the cron job doesn’t send automatic emails to the system user.

Option C: WP-CLI

If WP-CLI is installed on your server, this is often the most resource-friendly solution – no HTTP request, no network overhead:

*/5 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now --quiet 2>&1

wp cron event run --due-now starts all due events directly in the running PHP process. Prerequisite: WP-CLI is installed and the crontab user has read access to the WordPress directory.

Option D: External cron service

If your host has no cron interface and SSH isn’t available, external services help: cron-job.org (free), EasyCron (free up to a volume) or Uptime Robot (primarily monitoring, but sufficient for HTTP pings). Configure the URL there:

https://domain.tld/wp-cron.php?doing_wp_cron

Interval: five minutes. Note: this method always sends an HTTP request from outside – with very restrictive firewalls or IP whitelisting, it can fail.

Verification: Is the Cron Job Really Running?

After setting it up, wait at least ten minutes and then open WP Crontrol in the WordPress backend. The plugin shows the timestamp of the last run for each event. Overdue events that had piled up before should now be processed.

Additional check: call https://domain.tld/wp-cron.php?doing_wp_cron once manually in the browser. The page returns an empty response with no error message – that’s correct and shows the file is reachable. Then look at your server access log and search for regular GET /wp-cron.php entries at the chosen interval.

Common Mistakes and How to Fix Them

Scheduled posts don’t appear on time: the most common cause is a wrong path to wp-cron.php in the crontab entry. PHP gives no error in this case – the cron runs through, but with no effect. Check the path with ls /your/path/wp-cron.php directly on the server.

UpdraftPlus shows a red warning: backup plugins detect whether WP-Cron is active. After setting DISABLE_WP_CRON, this notice appears until a real cron job exists. Once set up correctly, it disappears automatically.

Crontab line isn’t executed: use crontab -l to check whether the line was saved correctly. Then test manually: bash -c "/usr/bin/php /path/to/wp-cron.php". If that fails, the executing user lacks permissions on the file.

Server sends emails after every cron run: the suffix >/dev/null 2>&1 is missing. Fix the crontab line and save.

When to Keep WP-Cron Instead

Shared hosting without cron access: anyone who has neither cPanel crons nor SSH and doesn’t want to use external services is better off with WP-Cron than with no automation at all. In that case, better to leave WP-Cron active and deregister superfluous events with WP Crontrol to lower the frequency.

Very simple sites without background tasks: a portfolio without a backup plugin, without scheduled posts and without an email queue has barely any events. The conversion effort outweighs the benefit.

Right before a migration or a major update: changes to wp-config.php don’t belong in a tight time window before a system change. Stabilise first, then optimise.



Not sure whether WP-Cron is slowing you down or tasks aren’t running? Drop us a line – we’ll set the cron job up cleanly.

You’ll find more performance levers for WordPress in the Core Web Vitals for WordPress overview.

Frequently Asked Questions

Should I disable WP-Cron in general?

Not as a blanket rule. On high traffic, WP-Cron creates unnecessary server load; on low traffic, it runs irregularly. Anyone with access to a real crontab or a hosting panel with a cron feature should switch. For simple sites without many background tasks, though, the effort is often greater than the gain.

What happens if I set DISABLE_WP_CRON but do not set up a real cron job?

Scheduled tasks stop running. Posts do not appear at their scheduled time, backups do not happen, and transactional emails can get stuck in the queue. Always set up the real cron job immediately after disabling.

How do I check whether my cron job is running?

The easiest way is the WP Crontrol plugin: it shows all scheduled events, their next run time, and whether they were processed successfully last time. Alternatively, check your server access log for regular calls to wp-cron.php.

Can I use WP-CLI instead of wget or curl in the crontab?

Yes, and it is often the cleaner solution. The command wp cron event run --due-now runs directly in the PHP process without HTTP overhead. The prerequisite is that WP-CLI is installed on the server and the executing user has read access to the WordPress directory.

Daniel Nilges
Daniel Nilges

Founder & Full-Stack Developer

20+ years of web development experience. Specialised in Laravel, WordPress and custom software for mid-sized businesses.