# Fix WordPress Cron Not Working

Scheduled posts aren't publishing. Automatic backups aren't running. Plugin scheduled tasks are failing. WordPress cron isn't working, and your automated tasks have stopped.

WordPress uses a pseudo-cron system called wp-cron. Unlike real system cron, it only runs when someone visits your site. This has limitations: low-traffic sites miss schedules, high-traffic sites cause performance problems, and certain configurations block wp-cron entirely.

Introduction

This article covers troubleshooting steps and solutions for Fix WordPress Cron Not Working. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.

Symptoms

Scheduled posts aren't publishing. Automatic backups aren't running. Plugin scheduled tasks are failing. WordPress cron isn't working, and your automated tasks have stopped.

WordPress uses a pseudo-cron system called wp-cron. Unlike real system cron, it only runs when someone visits your site. This has limitations: low-traffic sites miss schedules, high-traffic sites cause performance problems, and certain configurations block wp-cron entirely.

Common Causes

Check Scheduled Tasks

```bash # List all scheduled cron jobs wp cron event list

# Check for overdue tasks wp cron event list --fields=hook,next_run,status --status=pending

# Check specific scheduled time wp cron event list --fields=hook,next_run --format=table ```

Test Cron Execution

```bash # Run cron manually wp cron event run --due-now

# Run all cron events wp cron event run --all

# Test specific hook wp cron event run wp_version_check ```

Check if wp-cron.php is Accessible

```bash # Test wp-cron.php directly curl -I https://yourdomain.com/wp-cron.php

# Should return 200 OK, not 403 or 404 ```

Check wp-config Constants

bash
# Check if cron is disabled
grep -i "DISABLE_WP_CRON\|ALTERNATE_WP_CRON" wp-config.php

If define('DISABLE_WP_CRON', true); exists, wp-cron won't run automatically.

Step-by-Step Fix

1. Low Traffic Site

On low-traffic sites, cron only runs when someone visits. If no one visits, scheduled tasks don't run.

Solution: Set up a real system cron

```bash # Edit crontab crontab -e

# Add this line to run wp-cron every 5 minutes */5 * * * * curl -s https://yourdomain.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

# Or using WP-CLI (preferred) */5 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now --quiet ```

Then disable the pseudo-cron:

php
// Add to wp-config.php
define('DISABLE_WP_CRON', true);

2. wp-cron.php Blocked

Security plugins or server rules may block wp-cron.php.

Check .htaccess for blocks:

bash
grep -i "wp-cron" .htaccess

Check if blocked by security plugin:

bash
wp plugin list --status=active

Temporarily deactivate security plugins:

bash
wp plugin deactivate wordfence
wp plugin deactivate iThemes-security

Check server firewall:

bash
curl -I https://yourdomain.com/wp-cron.php

If blocked, whitelist wp-cron.php in your firewall or security plugin.

3. PHP Timeout on Cron

Long-running cron jobs may timeout.

Increase PHP timeout:

php
// In wp-config.php
set_time_limit(300);

Or in php.ini:

ini
max_execution_time = 300

4. Memory Limit

Cron jobs need memory too.

php
// In wp-config.php
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');

5. Missed Scheduled Posts

Posts scheduled but never published.

```bash # Check for missed schedule hook wp cron event list | grep -i miss

# Run missed schedule check wp cron event run publish_future_post

# Check scheduled posts wp post list --post_status=future --fields=ID,post_title,post_date ```

Manual fix for missed posts:

bash
# Get all future posts that should have been published
wp post list --post_status=future --field=ID | while read post_id; do
    wp post update $post_id --post_status=publish
done

Install Missed Schedule plugin:

bash
wp plugin install missed-schedule --activate

6. Cron Locked

WordPress uses a transient to prevent concurrent cron runs. If this gets stuck, cron won't run.

```bash # Check if cron is locked wp transient get doing_cron

# Delete the lock wp transient delete doing_cron

# Now run cron wp cron event run --due-now ```

7. WP-CLI Cron vs HTTP Cron

WP-CLI cron doesn't require HTTP access.

Set up WP-CLI system cron:

```bash # Edit crontab crontab -e

# Run WP-CLI cron every 5 minutes */5 * * * * cd /var/www/html && wp cron event run --due-now --quiet --user=1 ```

Disable HTTP cron:

php
// In wp-config.php
define('DISABLE_WP_CRON', true);

8. Server Timezone Mismatch

If server time doesn't match WordPress time, schedules appear incorrect.

```bash # Check server time date

# Check WordPress time wp option get timezone_string wp option get gmt_offset

# Check WordPress time wp eval 'echo current_time("mysql") . "\n";' ```

Set WordPress timezone:

bash
wp option update timezone_string "America/New_York"

Debug Cron Issues

Enable Cron Debugging

```php // In wp-config.php define('WP_DEBUG', true); define('WP_DEBUG_LOG', true);

// Add custom cron debugging add_action('init', function() { if (defined('DOING_CRON') && DOING_CRON) { error_log('Cron started at: ' . date('Y-m-d H:i:s')); } }); ```

Log Cron Execution

bash
# Tail the debug log during cron
tail -f wp-content/debug.log

Check Cron Schedules

```bash # List registered schedules wp eval ' $schedules = wp_get_schedules(); foreach ($schedules as $name => $schedule) { echo "$name: {$schedule["interval"]} seconds ({$schedule["display"]})\n"; } '

# Check specific scheduled event wp cron event list --fields=hook,schedule,next_run ```

Monitor Cron Execution

Add logging to specific hooks:

```php // In functions.php or custom plugin add_action('wp_scheduled_delete', function() { error_log('wp_scheduled_delete ran at: ' . date('Y-m-d H:i:s')); });

add_action('publish_future_post', function($post_id) { error_log("Published scheduled post ID: $post_id at: " . date('Y-m-d H:i:s')); }); ```

Optimize Cron Performance

Disable Unnecessary Cron Jobs

```bash # List all scheduled events wp cron event list --fields=hook,schedule

# Remove unnecessary events wp cron event delete wp_update_plugins wp cron event delete wp_update_themes ```

Consolidate Cron Jobs

If you have many plugins scheduling their own crons:

```php // Clear all plugin crons and consolidate // Then set up a single system cron that triggers a custom action

// Remove plugin crons wp_clear_scheduled_hook('plugin_daily_task'); wp_clear_scheduled_hook('plugin_hourly_task');

// Add consolidated schedule add_action('my_daily_maintenance', function() { do_action('plugin_daily_task'); // Other daily tasks });

wp_schedule_event(time(), 'daily', 'my_daily_maintenance'); ```

Use Alternative Cron Method

If wp-cron.php isn't working via HTTP:

php
// In wp-config.php
define('ALTERNATE_WP_CRON', true);

This uses a redirect method instead of spawning a separate process.

Check Specific Plugin Crons

WooCommerce

```bash # List WooCommerce scheduled actions wp wc tool list --field=name

# Run WooCommerce scheduled actions wp action-scheduler run

# Check pending actions wp action-scheduler list --status=pending ```

Backup Plugins

```bash # UpdraftPlus wp cron event list | grep updraft

# BackWPup wp cron event list | grep backwpup

# Run backup manually wp cron event run backwpup_cron ```

SEO Plugins

```bash # Yoast SEO wp cron event list | grep yoast

# Rank Math wp cron event list | grep rankmath ```

System Cron Setup Examples

Basic HTTP Cron

bash
*/5 * * * * wget -q -O - https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

WP-CLI Cron (Recommended)

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

With Logging

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

Multiple Sites (Multisite)

bash
*/5 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now --url=https://site1.com --quiet
*/5 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now --url=https://site2.com --quiet

Verification

After fixing cron:

```bash # Test cron runs wp cron event run --due-now

# Check for missed posts wp post list --post_status=future

# Check cron events are scheduled wp cron event list --status=pending

# Run test schedule wp cron event schedule test_event '+5 minutes' wp cron event list | grep test_event ```

Verification

  1. 1.[ ] Check if DISABLE_WP_CRON is set
  2. 2.[ ] Test wp-cron.php accessibility via curl
  3. 3.[ ] Delete stuck cron lock transient
  4. 4.[ ] Check server timezone matches WordPress timezone
  5. 5.[ ] Verify PHP memory and time limits
  6. 6.[ ] Check for security plugin blocks
  7. 7.[ ] Set up system cron for reliability
  8. 8.[ ] Monitor cron execution in debug.log

WordPress cron is fragile by design. The solution is almost always to set up a proper system cron that triggers wp-cron.php on a reliable schedule, then disable the pseudo-cron for consistent, predictable task execution.

  • [WordPress troubleshooting: Fix Child Theme Not Enqueuing Parent Styles Correc](child-theme-not-enqueuing-parent-styles-correctly)
  • [Fix Database Connection Error Custom Socket Path Issue in WordPress](database-connection-error-custom-socket-path)
  • [Fix Debug Log Growing Deprecated Warnings Notices Issue in WordPress](debug-log-growing-deprecated-warnings-notices)
  • [Fix Fix Contact Form Not Sending On Wordpress Site Issue in WordPress](fix-contact-form-not-sending-on-wordpress-site)
  • [Fix Fix Open Basedir Restriction Blocking Wordpress Issue in WordPress](fix-open-basedir-restriction-blocking-wordpress)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix WordPress Cron Not Working", "description": "Resolve WordPress cron failures. Fix scheduled posts not publishing, set up system cron for wp-cron.php, and debug wp_schedule issues.", "url": "https://www.fixwikihub.com/fix-wordpress-cron-not-working", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-17T13:04:11.730Z", "dateModified": "2025-11-17T13:04:11.730Z" } </script>