Written by 1:18 pm How To Views: 109

How to Disable WordPress Cron and Set Up a Real Server Cron Job

Learn how to disable WordPress WP-Cron and replace it with a real server cron job for better performance and reliable scheduling. Covers wp-config.php setup, cPanel crontab, WP-CLI cron commands, security hardening, monitoring missed events, and managed hosting considerations.

How to disable WordPress WP-Cron and set up a real server cron job

WordPress ships with a built-in task scheduler called WP-Cron. It handles scheduled posts, update checks, transient cleanup, email queues, and dozens of plugin-triggered jobs. But WP-Cron has a fundamental design flaw: it only runs when someone visits your site.

On a busy site, this means WP-Cron fires on every single page load, adding unnecessary overhead. On a quiet site, it means scheduled tasks might not run for hours or even days. Either way, replacing WP-Cron with a real server cron job gives you better performance and more reliable scheduling.

This guide covers exactly how to do it — from the one-line wp-config.php change to cPanel crontab setup, WP-CLI cron commands, and monitoring for missed events.

How WP-Cron Actually Works (And Why It’s a Problem)

Traditional Unix/Linux cron runs on a fixed schedule managed by the operating system. Every minute, the cron daemon checks if any jobs need to run. It runs regardless of whether anyone is using the server.

WP-Cron works differently. It piggybacks on HTTP requests:

  1. A visitor loads any page on your site
  2. WordPress checks the cron option in the database for pending jobs
  3. If jobs are due, WordPress spawns a separate HTTP request to wp-cron.php
  4. That request executes the pending jobs in the background

This design means:

ScenarioWhat Happens with WP-CronWhat Happens with Server Cron
High-traffic site (1000+ visits/hour)WP-Cron fires on every page load, adding ~50-200ms overhead per requestCron runs once per interval, zero overhead on page loads
Low-traffic site (10 visits/day)Scheduled posts publish late, emails queue for hoursCron runs on schedule regardless of traffic
Cached site (full-page cache)WP-Cron may never fire if cache serves all requestsCron runs independently of cache layer
Site behind load balancerMultiple servers may trigger duplicate cron runsSingle cron job runs from one server

If you have already explored other wp-config.php tweaks, you know that a single constant can dramatically change WordPress behavior. Disabling WP-Cron is one of the highest-impact changes you can make.

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

This is the simplest part. Open your wp-config.php file and add this line above the line that says /* That's all, stop editing! */:

define( 'DISABLE_WP_CRON', true );

This tells WordPress to stop checking for cron jobs on every page load. The cron system still exists — scheduled events are still registered in the database — but WordPress will no longer trigger them automatically.

Important: Do not delete this constant later thinking it will re-enable cron. If you want to re-enable WP-Cron, change true to false or remove the line entirely.

What About ALTERNATE_WP_CRON?

WordPress also supports ALTERNATE_WP_CRON, which uses a redirect-based approach instead of the loopback HTTP request. This is sometimes recommended for sites where the server cannot make HTTP requests to itself (common with some security configurations).

define( 'ALTERNATE_WP_CRON', true );

However, this still runs on page loads. If your goal is to eliminate cron overhead entirely, DISABLE_WP_CRON plus a real server cron is the better approach.

Step 2: Set Up a Real Server Cron Job

With WP-Cron disabled, you need an alternative to trigger scheduled tasks. Here are three methods, from simplest to most robust.

Method 1: cPanel Cron Job (Shared Hosting)

Most shared hosting providers offer cron job management through cPanel:

  1. Log into your hosting control panel (cPanel, Plesk, or similar)
  2. Find “Cron Jobs” under the Advanced section
  3. Set the frequency — every 5 minutes is the recommended starting point
  4. Add this command:
wget -q -O /dev/null https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Or if wget is not available, use curl:

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

Replace yourdomain.com with your actual domain.

Method 2: SSH Crontab (VPS/Dedicated Server)

If you have SSH access, edit the crontab directly:

crontab -e

Add this line to run WordPress cron every 5 minutes:

*/5 * * * * cd /var/www/yourdomain.com/htdocs && php wp-cron.php >/dev/null 2>&1

This method is faster than wget/curl because it calls PHP directly instead of making an HTTP request. No web server overhead, no SSL handshake, no redirect handling.

Method 3: WP-CLI Cron (Recommended)

If WP-CLI is installed on your server, this is the most reliable method:

*/5 * * * * cd /var/www/yourdomain.com/htdocs && wp cron event run --due-now --quiet >/dev/null 2>&1

Why WP-CLI is better:

  • Runs in the CLI context, not the web context — no HTTP overhead
  • Handles multisite correctly with the --url flag
  • The --due-now flag only runs events that are actually due, not all registered events
  • Better error handling and logging capabilities

For WordPress multisite:

*/5 * * * * cd /var/www/yourdomain.com/htdocs && wp cron event run --due-now --url=site1.com --quiet >/dev/null 2>&1
*/5 * * * * cd /var/www/yourdomain.com/htdocs && wp cron event run --due-now --url=site2.com --quiet >/dev/null 2>&1

Step 3: Choose the Right Frequency

How often should the cron job run? It depends on what your site does:

Use CaseRecommended FrequencyWhy
Blog with scheduled postsEvery 5 minutesPosts publish within 5 minutes of scheduled time
WooCommerce storeEvery 1-2 minutesOrder processing, stock updates, and email notifications need near-real-time execution
Membership siteEvery 5 minutesSubscription renewals, drip content, and access checks
Low-traffic brochure siteEvery 15 minutesOnly update checks and transient cleanup needed
Site with email automationEvery 1-2 minutesTime-sensitive email delivery

Do not run cron every minute unless you have a specific reason. Every cron execution loads WordPress core, which consumes CPU and memory. On shared hosting, running too frequently can trigger resource limits.

Step 4: Verify Your Cron Job Is Working

After setup, verify that scheduled events are actually running.

Using WP-CLI

List all scheduled cron events:

wp cron event list

This shows every registered event, its next run time, and the hook name. Check that the “Next Run” times are in the past (meaning they are due) or in the near future (meaning they have been running on schedule).

Test a specific cron event manually:

wp cron event run wp_update_plugins

Using a Plugin

If you do not have WP-CLI access, install the WP Crontrol plugin. It provides a dashboard showing:

  • All registered cron events and their schedules
  • When each event last ran
  • Overdue events that have not been triggered
  • The ability to run events manually

Manual Verification

Create a simple test: schedule a post for 5 minutes from now. If it publishes on time (within your cron interval), the server cron is working correctly.

Monitoring for Missed Cron Events

Even with a server cron job, events can be missed if your server is under heavy load, PHP memory limits are hit, or a long-running event blocks subsequent ones.

WP-CLI Monitoring Script

Create a monitoring script that alerts you when events are overdue:

#!/bin/bash
# Check for overdue WordPress cron events
OVERDUE=$(cd /var/www/yourdomain.com/htdocs && wp cron event list --fields=hook,next_run_relative --format=csv | grep 'ago' | wc -l)

if [ "$OVERDUE" -gt 5 ]; then
  echo "WARNING: $OVERDUE overdue WordPress cron events" | mail -s "WP Cron Alert" [email protected]
fi

Add this to your crontab to run once per hour:

0 * * * * /path/to/cron-monitor.sh

Common Causes of Missed Events

  • PHP memory limit — A single cron event consuming too much memory kills the process before other events run. Increase memory_limit in php.ini or check which event is memory-heavy.
  • Execution timeout — Long-running events hit PHP’s max_execution_time. For CLI execution, this is usually unlimited, but verify with php -i | grep max_execution_time.
  • Lock conflicts — WordPress uses a transient lock to prevent overlapping cron runs. If a previous run crashed without releasing the lock, subsequent runs are blocked. Clear it with: wp transient delete doing_cron
  • Database lock waits — Heavy wp_options table bloat can cause slow queries during cron execution. Cleaning up autoloaded options helps.

WP-Cron and Object Caching

If you use Redis or Memcached for object caching, be aware that cron event scheduling is stored in the cron option in the database, not in the object cache. However, the object cache can affect how quickly WordPress reads cron data.

If you notice cron events being duplicated or running at unexpected times after enabling object caching, flush the object cache:

wp cache flush

WordPress Cron Intervals Explained

WordPress defines three default cron intervals:

Interval NameFrequencySeconds
hourlyOnce per hour3600
twicedailyEvery 12 hours43200
dailyOnce per day86400
weeklyOnce per week (added in WP 5.4)604800

Plugins can register custom intervals using the cron_schedules filter. If you need a custom interval (for example, every 15 minutes), add this to your theme’s functions.php or a custom plugin:

add_filter( 'cron_schedules', function( $schedules ) {
    $schedules['every_fifteen_minutes'] = array(
        'interval' => 900,
        'display'  => 'Every 15 Minutes',
    );
    return $schedules;
} );

Security Considerations

The wp-cron.php file is publicly accessible by default. This means anyone can trigger your cron jobs by visiting yourdomain.com/wp-cron.php. While this is generally harmless, it can be abused for denial-of-service attacks if your cron events are resource-intensive.

Once you have a server cron job running, block public access to wp-cron.php via .htaccess:

# Block direct access to wp-cron.php
<Files wp-cron.php>
    Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1
    Allow from ::1
</Files>

For Nginx:

location = /wp-cron.php {
    allow 127.0.0.1;
    allow ::1;
    deny all;
}

If you are using the wget/curl method from an external cron service, do not block the file. The WP-CLI method runs locally and does not need HTTP access to wp-cron.php.

Managed Hosting: What to Know

Many managed WordPress hosts (WP Engine, Kinsta, Flywheel, Cloudways) handle cron differently:

  • WP Engine — Automatically disables WP-Cron and runs a system-level cron every minute
  • Kinsta — Disables WP-Cron by default and runs server cron every 15 minutes. You can request a shorter interval via support.
  • Flywheel — Similar to Kinsta. Server cron runs every 15 minutes.
  • Cloudways — Provides a cron job manager in the dashboard. You control the interval.
  • SiteGround — Offers cron job setup through their Site Tools panel

Check with your host before adding a manual cron job — you may already have one running, and adding a second could cause duplicate event execution.

Debugging Cron Issues

When cron events are not running as expected, use the WordPress debug log to identify the problem:

  1. Enable debug logging in wp-config.php:
    define( 'WP_DEBUG', true );
    define( 'WP_DEBUG_LOG', true );
    define( 'WP_DEBUG_DISPLAY', false );
  2. Run cron manually via WP-CLI and check the log:
    wp cron event run --due-now
    tail -50 wp-content/debug.log
  3. Look for PHP errors, timeout warnings, or memory exhaustion messages

For a complete guide to reducing database bloat that can slow down cron execution, see our post revisions guide.

Frequently Asked Questions

Will disabling WP-Cron break my scheduled posts?

No, as long as you set up a server cron job as a replacement. The server cron triggers the same scheduled events that WP-Cron would, just more reliably. Your posts will publish on schedule within the interval you configure (typically every 5 minutes).

Is it safe to disable WP-Cron on WooCommerce sites?

Yes, and it is actually recommended. WooCommerce relies heavily on cron for order processing, stock management, and email notifications. A server cron job ensures these tasks run on time regardless of site traffic. Set the interval to every 1-2 minutes for WooCommerce sites.

How do I know if my server cron job is working?

Use WP-CLI to list cron events: wp cron event list. If events show recent execution times and no overdue jobs, your cron is working. You can also schedule a test post 5 minutes in the future — if it publishes on time, cron is running correctly.

What is the difference between DISABLE_WP_CRON and ALTERNATE_WP_CRON?

DISABLE_WP_CRON completely stops WordPress from triggering cron on page loads. ALTERNATE_WP_CRON changes the trigger mechanism from a loopback HTTP request to a redirect-based approach but still runs on page loads. For best performance, use DISABLE_WP_CRON with a server cron job.

Can I disable WP-Cron on shared hosting?

Yes. Most shared hosting providers (cPanel-based) offer a cron job manager where you can add a wget or curl command to call wp-cron.php at regular intervals. Disable WP-Cron in wp-config.php first, then set up the cron job in your hosting panel.

How often should I run the server cron job?

Every 5 minutes is a good default for most sites. WooCommerce and email-heavy sites should use 1-2 minutes. Low-traffic brochure sites can use 15 minutes. Avoid running every minute unless necessary, as each execution loads WordPress core and consumes server resources.

Do managed WordPress hosts already handle this?

Most managed hosts (WP Engine, Kinsta, Flywheel) automatically disable WP-Cron and run their own server-level cron. Check your host’s documentation before adding a manual cron job to avoid duplicate execution.

Visited 109 times, 1 visit(s) today

Last modified: March 25, 2026