Disable WP-Cron and Use Server Cron

If your WordPress site feels sluggish or your server CPU spikes unexpectedly, WP-Cron may be the culprit. WordPress ships with its own pseudo-cron system — wp-cron.php — that runs scheduled tasks (backups, email, update checks) by triggering on every page load. On busy sites, this means hundreds of extra PHP processes every hour. The fix is straightforward: disable WP-Cron and replace it with a real server cron job.

The core problem: WP-Cron doesn't run on a schedule — it runs on every HTTP request. A site receiving 1,000 visits/hour potentially triggers wp-cron.php 1,000 times per hour, even if scheduled tasks only need to run once.

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

Open your wp-config.php file (in the WordPress root directory) and add this line before the /* That's all, stop editing! */ comment:

define('DISABLE_WP_CRON', true);

This prevents WordPress from spawning its internal cron on every page load. Scheduled events will not run until you set up the real cron job in Step 2.

Do not skip Step 2. After disabling WP-Cron, WordPress will not run any scheduled tasks until a real cron job is configured. Backups, update notifications, and scheduled posts will all stop working temporarily.

Step 2: Set Up a Real Cron Job on DirectAdmin

  1. Log in to DirectAdmin → Advanced Features → Cron Jobs
  2. Set the schedule to run every 5 minutes (recommended) or every 1 minute for high-traffic sites
  3. Enter this command:
wget -q -O /dev/null "https://yourdomain.com/wp-cron.php?doing_wp_cron" >/dev/null 2>&1

Or use curl if wget is not available:

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

Replace yourdomain.com with your actual domain. The >/dev/null 2>&1 part suppresses all output so you don't get cron emails every 5 minutes.

Crontab Schedule Reference

Cron Expression Meaning
*/1 * * * *Every 1 minute
*/5 * * * *Every 5 minutes (recommended)
0 * * * *Every hour, on the hour
0 0 * * *Daily at midnight

Step 3: Verify with WP Crontrol Plugin

WP Crontrol (free on WordPress.org) lets you view, edit, delete, and manually run all cron events in WordPress. After setting up the server cron job:

  1. Install WP Crontrol from Plugins → Add New
  2. Go to Tools → Cron Events
  3. Check the "Next Run" time for events — they should update correctly after your server cron fires
  4. You can also add or remove custom cron events from this screen

Understanding Cron Expressions Before You Configure

Whether you use DirectAdmin's cron job UI or a raw crontab, you need to understand cron expression syntax. A cron expression has five fields: Minute, Hour, Day of Month, Month, and Day of Week. Each field accepts a number, an asterisk (every), or a step value like */5 (every 5).

ExpressionMeaningBest for
*/5 * * * *Every 5 minutesMost WordPress sites (recommended)
*/1 * * * *Every 1 minuteHigh-traffic sites needing precision
0 * * * *Every hour on the hourVery low-traffic sites
0 2 * * *Daily at 2:00 AMDaily backup jobs
0 0 * * 0Every Sunday at midnightWeekly maintenance tasks

Not sure if your expression is correct? Use AsiaGB's free Cron Expression Generator to build and validate expressions without memorizing the syntax.

Common Problems After Disabling WP-Cron

After disabling WP-Cron and setting up a server cron job, you may encounter these issues if something is misconfigured:

Scheduled Posts Are Not Publishing

Cause: the server cron job is not running because the PHP binary path is wrong. Verify the correct path with which php via SSH. Some servers require php8.1 or php8.2 instead of just php.

# Find the correct PHP path
which php
# or check alternatives
ls /usr/bin/php*

Cron Emails Flooding Your Inbox

Add > /dev/null 2>&1 at the end of your cron command to discard all output, or set MAILTO="" as the first line of your crontab to suppress all emails globally:

MAILTO=""
*/5 * * * * php /home/username/domains/example.com/public_html/wp-cron.php > /dev/null 2>&1

Backup Plugin Is Not Running on Schedule

Plugins like UpdraftPlus and BackWPup rely on WordPress Cron to trigger their own scheduled backups. With a real server cron running wp-cron.php every 5 minutes, those plugin tasks will fire at their configured times — no additional configuration needed. The server cron simply ensures the WordPress cron queue is processed reliably.

Pro tip: Schedule heavy backup jobs between 1:00 AM and 4:00 AM when traffic is lowest. This keeps CPU usage predictable and ensures backups complete without competing with live visitor requests.

WP-Cron on WordPress Multisite Networks

On a WordPress Multisite installation, disabling WP-Cron works the same way but with one key difference: you only need to make one change and set up one cron job regardless of how many sub-sites you have.

Before vs After: Performance Impact

Aspect WP-Cron (default) Server Cron
TriggerEvery page loadEvery 5 minutes exactly
Page load impactAdds PHP overhead to all requestsZero impact on page loads
ReliabilityRequires visitors to triggerRuns even with no traffic
CPU usageHigh on busy sitesPredictable, low overhead

Securing wp-cron.php After Disabling WP-Cron

Once you switch to a server cron job, the file wp-cron.php is still publicly accessible via HTTP. This exposes a potential attack vector: anyone can send HTTP requests to trigger your cron queue or attempt a denial-of-service attack by flooding it with requests. The solution is to block public access to the file while keeping the server-side cron job working.

Block Access on Apache (.htaccess)

Add these lines to the .htaccess file in your WordPress root directory:

# Block public access to wp-cron.php
<Files wp-cron.php>
  Order allow,deny
  Deny from all
  Allow from 127.0.0.1
</Files>

This allows only localhost (127.0.0.1) to access wp-cron.php, which is sufficient when the cron job runs via PHP CLI rather than HTTP.

Block Access on Nginx

# Inside your Nginx server block
location = /wp-cron.php {
    allow 127.0.0.1;
    deny  all;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Note: If you use curl or wget in your cron command instead of PHP CLI, update the cron command to call localhost directly: curl -s http://127.0.0.1/wp-cron.php?doing_wp_cron -H "Host: yourdomain.com" — this avoids triggering your own firewall block.

Using WP-CLI for Cron Jobs

If your hosting supports WP-CLI (WordPress Command Line Interface), it offers a more powerful alternative to running wp-cron.php directly. The command wp cron event run --due-now processes only events that are actually due, with better error visibility:

# WP-CLI cron command (replace php path with WP-CLI runner)
*/5 * * * * /usr/local/bin/wp cron event run --due-now \
  --path=/home/username/domains/example.com/public_html \
  --quiet > /dev/null 2>&1
MethodAdvantagesLimitations
PHP CLI (wp-cron.php)Works on any hosting, simple setupMust use correct PHP binary path
WP-CLIDetailed logs, easy to debugRequires WP-CLI installed on server
curl / wget (HTTP)No shell access neededHTTP overhead, IP must be allowed

Troubleshooting Cron Jobs That Are Not Running

If you have set up a server cron job but WordPress tasks still aren't running on schedule, check the cron daemon log first — most failures stem from an incorrect PHP path, insufficient file permissions, or a missing environment variable.

# Check cron logs on CentOS / AlmaLinux
tail -50 /var/log/cron

# Check cron logs on Ubuntu / Debian
grep CRON /var/log/syslog | tail -50

# Test your cron command manually in shell
php /home/username/domains/example.com/public_html/wp-cron.php
echo $?   # Should return 0 (success)

If the command works in a terminal session but fails silently in a cron job, the cause is almost always the PATH environment variable — the cron environment has a much narrower PATH than your interactive shell. Fix this by specifying absolute paths for all binaries:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/5 * * * * /usr/bin/php8.2 /home/username/domains/example.com/public_html/wp-cron.php > /dev/null 2>&1

Long-Term Maintenance: What to Check After Migration

After switching from WP-Cron to a real server cron job, add these checks to your site maintenance routine to ensure everything remains healthy over time:

Final verification: Wait 10–15 minutes after setup, then open WP Crontrol (Tools → Cron Events). If the "Next Run" timestamps for all events are updating correctly relative to your schedule, the server cron job is working perfectly.

WordPress Hosting with DirectAdmin Cron Job Support

AsiaGB Hosting includes DirectAdmin with full cron job management. Set up server-side cron jobs without command-line access. Starting at 500 THB/year.

View Hosting Plans →