WordPress doesn't have a real background scheduler. By default, every page load checks whether any scheduled task (post publishing, plugin cleanup jobs, backup triggers) is due, and if so, fires it right then. This is WP-Cron, and it works fine on busy sites. On a low-traffic site, it fails quietly: no visitor, no page load, no check, so scheduled posts publish late, plugin maintenance tasks pile up, and anything time-sensitive drifts. The fix is to turn off the page-load trigger and run wp-cron.php on a real, fixed schedule instead.
The symptom
Scheduled posts stay stuck in "Scheduled" past their publish time. Plugins that rely on WP-Cron for cleanup, cache warming, or license checks fall behind. Backup plugins skip runs. If you check a scheduled task's next-run time and it keeps sliding later instead of firing on time, WP-Cron is the first suspect.
Confirm it's WP-Cron before you fix anything
Install WP Crontrol (or check via a similar tool) and look at the scheduled events list. If events show as overdue by hours or days, and your site gets sparse traffic, that's consistent with WP-Cron starvation. If events are missing entirely, that's usually a different problem: a plugin failed to register its schedule, or something is silently swallowing the wp_schedule_event call. Don't skip this check. Disabling WP-Cron on a site where the real problem is a missing schedule removes your fallback without fixing anything.
Three most likely causes on our stack
1. Low or bursty traffic
This is the most common cause by far. WP-Cron piggybacks on page loads. A site that gets a handful of visits a day, or traffic concentrated in a few hours, leaves long gaps where nothing checks the schedule. Tasks queued for 3am sit untouched until the first visitor arrives the next morning, if one does.
2. Caching serving pages without triggering PHP
If a page is served from LiteSpeed Cache (installed and preconfigured on WordPress sites with us) or any full-page cache, the request never reaches WordPress's PHP layer, so the WP-Cron check embedded in wp-load.php never runs. Heavily cached sites can look like they have decent traffic in your analytics while WP-Cron rarely actually fires, because most of those hits are cache hits.
3. A plugin or theme already disabled it, badly
Some plugins set DISABLE_WP_CRON to true in wp-config.php to "improve performance" without setting up a replacement trigger. If that's the case on your site, scheduled tasks have been silently not running at all, not running late. Check wp-config.php for this line before assuming the problem is traffic-related.
The fix: real server cron
The fix is the same regardless of which cause applies: stop relying on page loads, and call wp-cron.php on a fixed interval using a real cron job.
Step 1: disable the page-load trigger
Edit wp-config.php and add, above the line that says /* That's all, stop editing! */:
define('DISABLE_WP_CRON', true);
This stops WordPress from checking the schedule on every page load. Scheduled tasks won't run at all until you set up the replacement in the next step, so don't stop here.
Add a new job that runs a command like:
wget -q -O /dev/null "https://yourdomain.com/wp-cron.php?doing_wp_cron"
or, if you'd rather use curl:
curl -s "https://yourdomain.com/wp-cron.php?doing_wp_cron" > /dev/null
Every 15 minutes works for most sites. On stores or sites with time-sensitive scheduled actions, a shorter interval such as every 5 minutes can help, though on most hosting accounts going below 5 minutes rarely has enough queued work to be worth it.
Step 3: confirm it's actually running
Wait for the interval to pass, then check WP Crontrol again. Scheduled events should show next-run times in the near future rather than slipping backward. If a scheduled post was stuck, it should publish on the next cron hit after its scheduled time.
A note on caching interference
Since wp-cron.php is a script, not a normal page, it shouldn't be cached, but double-check your LiteSpeed Cache exclusion rules if you've customized them. A cached or otherwise short-circuited response from wp-cron.php means your server cron job is "running" successfully while doing nothing.
When to open a ticket
If you've disabled DISABLE_WP_CRON, added the Cron Jobs entry, confirmed it's hitting the URL on schedule, and tasks are still not firing, that points at something deeper, like a plugin conflict intercepting the request or a PHP error inside wp-cron.php itself. Turning on debug logging as described in fixing the WordPress white screen of death will often surface the error. If the log doesn't make the cause obvious, open a ticket from Support in the portal.