WP Tango

How to Stop WordPress Cron Failures for Good

Learn how to stop WordPress cron failures by checking loopbacks, replacing traffic-driven wp-cron, and fixing blocked tasks before they hurt store sales.

September 3, 2026
How to Stop WordPress Cron Failures for Good

WordPress cron failures are not a cosmetic admin warning. They can stop scheduled posts, abandoned-cart emails, subscription renewals, backups, malware scans, inventory syncs, and WooCommerce order processing. To stop WordPress cron failures, first identify whether WP-Cron is failing because it cannot trigger itself, because your server is blocking loopback requests, or because scheduled jobs are taking too long to finish. Then replace traffic-dependent triggering with a real server cron job where appropriate.

WP-Cron is often misunderstood. It is not a true system scheduler by default. WordPress checks for due events when someone visits your site, then makes a background request to `wp-cron.php`. That design is acceptable for a low-traffic brochure site. It becomes unreliable when traffic is sparse, the site is busy, or the server blocks the request WordPress uses to launch cron.

Confirm what is actually failing

Start in Tools > Site Health. A common message is: "The scheduled event, wp_version_check, failed to run." That message names one missed event, not necessarily the root cause. Look for failed loopback requests, REST API failures, or recurring missed schedule notices.

If you have WP-CLI access, inspect WordPress's scheduled event queue directly:

bash
wp cron event list --fields=hook,next_run,recurrence

Pay attention to events whose `next_run` time is far in the past. A few seconds of delay is normal. Events delayed by minutes or hours indicate a trigger or execution problem. On WooCommerce sites, also inspect Action Scheduler. It is WooCommerce's separate task queue, used for tasks such as webhooks, subscriptions, follow-up emails, and database cleanup.

bash
wp action-scheduler list --status=pending --per-page=20

A growing backlog of pending actions means the site is not processing jobs quickly enough. Do not treat that as a reason to blindly increase PHP limits. First determine whether jobs are not starting or are starting and failing.

The usual reasons WordPress cron fails

Most WP-Cron incidents fall into a small number of categories. The fix depends on which category you have.

| Symptom | Likely cause | What to check | |---|---|---| | Scheduled posts publish late | Low site traffic or disabled cron | Trigger frequency and `DISABLE_WP_CRON` | | Site Health reports loopback errors | Firewall, basic auth, DNS, SSL, or security plugin | Server and application logs | | WooCommerce actions pile up | Slow jobs, limited PHP workers, or fatal errors | Action Scheduler logs and PHP error log | | Cron runs constantly | High traffic repeatedly triggers `wp-cron.php` | Access logs and real-cron configuration | | Events fail after migration | Old URL, broken SSL, or restrictive server policy | `home` and `siteurl`, DNS, outbound HTTP |

Low traffic creates missed schedules

A site with a few visits per day has no dependable trigger for default WP-Cron. If an event is due at 2:00 AM and nobody visits until 9:00 AM, WordPress will not notice it until 9:00 AM. That is not a server failure. It is the default design working exactly as designed.

This matters for stores. A delayed renewal or fulfillment webhook can become a customer support problem long before anyone sees a Site Health warning.

Loopback requests are blocked

WordPress launches its cron runner by making an HTTP request back to its own site. Security layers sometimes interpret that as suspicious traffic. Common blockers include a web application firewall, a security plugin, HTTP basic authentication on staging, Cloudflare rules, restrictive ModSecurity policies, and servers that cannot resolve the site's public hostname correctly.

Test the cron endpoint from the server if you have shell access:

bash
curl -I https://example.com/wp-cron.php?doing_wp_cron

You want a normal HTTP response, usually `200`, without a redirect loop, authentication challenge, or connection timeout. A `403` response points toward a firewall or security rule. A timeout often points to DNS, networking, exhausted PHP workers, or an application request that is hanging.

Do not permanently allow all traffic to `wp-cron.php` from the internet just to silence the error. A properly configured system cron can call it locally or through a controlled request, reducing exposure and avoiding a public workaround.

Jobs are too heavy for the available workers

Cron tasks use PHP workers. If all workers are busy serving uncached pages, checkout requests, or slow plugin operations, cron can wait or time out. This is common on WooCommerce stores with a small worker pool, expensive cart logic, and plugins that schedule large imports or bulk email jobs.

Check the PHP error log for memory exhaustion, max execution time errors, and fatal plugin errors at the same timestamp as missed events. Also inspect database performance. A scheduled task that scans a bloated `wp_postmeta` table or processes thousands of queued records can consume a worker for minutes.

Increasing `max_execution_time` may help a legitimate long-running import, but it can also make worker contention worse. Split large jobs into batches, reduce batch sizes in the responsible plugin if supported, and remove abandoned queues rather than giving one broken task more time to block the system.

Stop WordPress cron failures with a real cron job

For production sites, especially WooCommerce stores, the dependable fix is usually to disable WordPress's visitor-triggered cron and schedule it at the server level. This gives jobs a predictable trigger regardless of traffic and prevents every site visit from checking the cron queue.

First, add this line above the "That's all, stop editing" comment in `wp-config.php`:

php
define('DISABLE_WP_CRON', true);

Only add that constant after scheduling a real cron job. If you disable WP-Cron without a replacement, no scheduled events will run.

On a Linux server with WP-CLI, a practical crontab entry runs due events every five minutes:

bash
/5    * cd /path/to/wordpress && /usr/local/bin/wp cron event run --due-now --quiet >/dev/null 2>&1

The exact paths vary by host. Run `which wp` to locate WP-CLI, and use the actual WordPress document root. Five minutes is appropriate for many content sites. Stores that rely on time-sensitive queues may need one-minute execution, provided the jobs finish quickly and the server has sufficient PHP capacity.

If WP-CLI is unavailable, schedule a command-line HTTP request instead:

bash
/5    * curl -fsS https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

WP-CLI is generally the better option because it avoids unnecessary web-server, TLS, and proxy layers. The HTTP approach is still workable when server access is limited. Never schedule both methods at the same frequency unless you understand the duplicate-trigger risk.

Fix the application issues a real cron will expose

A real cron job guarantees that WordPress attempts the work. It cannot fix a plugin task that crashes every time it runs. After changing the trigger, watch the first several runs.

For WordPress core events, test execution manually:

bash
wp cron event run --due-now

For a specific hook, run it by name:

bash
wp cron event run wp_version_check

If execution produces a fatal error, update or roll back the responsible plugin on staging before touching production. If the failure happens only under cron, compare the PHP version, environment variables, file permissions, and user account used by the scheduled command with those used by normal web requests.

On WooCommerce, review failed actions in WooCommerce > Status > Scheduled Actions. A repeated failure often identifies the plugin hook and error message directly. Do not bulk-delete pending actions unless you know what created them. Deleting a subscription renewal, payment retry, or fulfillment action can create a more serious operational problem than the queue backlog.

Check infrastructure before blaming WordPress

Cron reliability is tied to the same infrastructure issues that cause slow TTFB and inconsistent checkout performance. A server with overloaded CPU, exhausted PHP workers, slow disk I/O, or a database under lock contention will eventually delay background work.

Look for correlated signals: high CPU at cron times, a rising PHP-FPM queue, MySQL slow queries, repeated 502 or 504 errors, and backups competing with checkout traffic. Object caching can reduce repeated database work, but it will not fix a cron callback that performs a huge uncached query or contacts a slow third-party API.

This is where managed infrastructure should provide evidence, not vague reassurance. On a platform such as WP Tango, high-frequency AMD Ryzen 9950X resources, server-level caching, and operational visibility give busy sites more headroom. But even fast hardware needs sane queue design, enough workers, and scheduled tasks that fail visibly rather than silently.

Keep cron from becoming tomorrow's outage

After the immediate fix, add cron to your maintenance checks. Confirm that a known recurring event advances on schedule, review WooCommerce failed actions weekly, and alert on PHP fatal errors. Before plugin updates, test whether the plugin registers or changes scheduled jobs on staging.

The goal is not to make `wp-cron.php` look healthy for one afternoon. It is to make sure your store, publishing workflow, backups, and customer emails still run when traffic drops, load spikes, or a plugin behaves badly. That is the difference between a scheduled task system and a hidden point of failure.

Keep reading