The Problem

WordPress's wp-cron runs on every page load, which means on high-traffic sites it can spawn multiple overlapping processes. This causes duplicate emails, scheduled posts published multiple times, and excessive server load.

Symptoms

  • Duplicate scheduled emails sent to users
  • Scheduled posts published multiple times
  • High CPU and memory usage during peak traffic
  • wp-cron.php processes stacking up in ps aux
  • Backup plugins running multiple times simultaneously

Real Error Scenario

```bash # Check for overlapping wp-cron processes ps aux | grep wp-cron.php

# Output shows multiple simultaneous processes: # www-data 1234 45.2 3.1 /usr/bin/php wp-cron.php # www-data 1235 44.8 3.0 /usr/bin/php wp-cron.php # www-data 1236 43.1 2.9 /usr/bin/php wp-cron.php ```

How It Happens

Every time someone visits the site, WordPress checks if any scheduled tasks are due. If 100 visitors arrive simultaneously and a task is due, all 100 requests may trigger the same task.

How to Fix It

Fix 1: Disable WP-Cron and Use System Cron

php
// wp-config.php - Disable the default behavior
define('DISABLE_WP_CRON', true);

```bash # Add to system crontab (runs every 5 minutes) crontab -e

# Add this line: */5 * * * * cd /var/www/html && /usr/bin/php wp-cron.php --doing_wp_cron >/dev/null 2>&1 ```

This ensures wp-cron runs exactly once every 5 minutes, regardless of traffic.

Fix 2: Use Transient Locking

```php // Add to your theme's functions.php function run_locked_cron($callback) { $lock_name = 'my_cron_lock';

if (get_transient($lock_name)) { return; // Another instance is running }

set_transient($lock_name, true, 300); // 5 minute lock

try { $callback(); } finally { delete_transient($lock_name); } }

// Usage: run_locked_cron(function() { send_newsletter(); }); ```

Fix 3: WP-CLI Cron with Single Execution

```bash # Run specific cron event wp cron event run --due-now --path=/var/www/html

# List all scheduled events wp cron event list --path=/var/www/html

# Delete stuck events wp cron event delete woocommerce_cleanup_sessions ```

Fix 4: Monitor Cron Queue Size

```bash # Check the cron option size (large = problem) wp option get cron --format=json | jq 'keys | length'

# If the number is very large (1000+), clean it up: wp option update cron '{}' --format=json # Then re-register your plugin's cron events ```

Fix 5: Use a Cron Management Plugin

Install WP Crontrol to view, edit, and manage scheduled events from the WordPress admin dashboard.

bash
Tools -> Cron Events

Look for: - Events scheduled in the past but not executed - Duplicate events with the same hook - Events with very short intervals (< 1 minute)