How to Fix WP-Cron When Scheduled Posts Miss on a Fan Site
You schedule the patch notes summary for 03:00, right when the servers come back from maintenance. You wake up at 08:30 and the post still says "Missed schedule" in red.

You schedule the patch notes summary for 03:00, right when the servers come back from maintenance. You wake up at 08:30 and the post still says "Missed schedule" in red. Discord already has three threads asking where the notes are, and someone linked a rival wiki instead. Nothing crashed. WordPress simply never got around to publishing.
The culprit is almost always WP-Cron, the system WordPress uses for anything timed: scheduled posts, backup plugins, newsletter sends, cache clearing. I ran a clan site and a fan wiki for years before I figured out how it really works, and the fix took me about fifteen minutes once I understood it. This guide covers why it fails on small community sites, how to check what is stuck, and how to move it to a real timer.
Why WP-Cron misses on quiet sites
WP-Cron is not a clock. It does not run in the background waiting for 03:00. Instead, every time someone loads a page, WordPress checks a list of due tasks stored in the database and, if anything is overdue, fires a quick request to itself at wp-cron.php to run them.
That design works fine on a site with steady traffic. It falls apart on a gaming fan site, where traffic comes in bursts. At 03:00 on a Tuesday your guild site might get zero visitors for two hours. No visitor means no page load, which means no check, which means the post sits there. When the first visitor does show up at 05:40, WordPress may publish then, or it may mark the post missed if a plugin or setting interferes with the loopback request.
A few other things break it even with traffic:
- Full-page caching. If your cache plugin or host serves cached HTML, PHP never runs on those requests, so WordPress never checks the task list. I covered a related headache in the guide on caching plugins that hide your own updates.
- Blocked loopback requests. Some security plugins and firewalls block the site from calling itself. Site Health will tell you: look for "Your site could not complete a loopback request".
- Basic auth on staging or maintenance mode. A password prompt stops the self-request cold.
- A stuck lock. WP-Cron sets a lock while it runs. If a long task dies halfway, the lock can block new runs for up to 60 seconds per attempt, and a plugin that keeps crashing will keep relocking it.
Check what is actually queued
Before changing anything, look at the queue. Install WP Crontrol, which is free and maintained by a long-time core contributor. Go to Tools, then Cron Events. You will see every scheduled task, its hook name, the next run time, and how often it repeats.
On a typical clan site with around 30 plugins I usually find 40 to 70 events. Look for three things. First, events with a next-run time in the past, shown in red or with "late" beside them. Second, duplicate events from the same plugin, sometimes dozens of copies, which happen when a plugin schedules itself on every page load by mistake. Third, events left behind by plugins you deleted months ago. Those orphans still fire, find no code to run, and waste a request each time.
Delete the orphans and the duplicates from the WP Crontrol screen. If you went through a plugin cleanup recently, this step finishes the job; my notes on removing unused plugins without leftovers explain why deactivating alone leaves this mess behind.
The common fix that only half works
Most tutorials say: install a "missed schedule" plugin and move on. These plugins check for overdue posts on each page load and force them out. They do help a little, but they rely on the exact same trigger that failed in the first place, a visitor arriving. On a quiet site at 03:00 they do nothing until someone shows up. You get your post at 05:40 instead of never, which is better, but not what you scheduled.
The other popular tip is to raise the PHP time limit so long tasks finish. That treats a symptom. If a backup plugin needs four minutes inside a visitor's page request, the real problem is that it is running inside a visitor's page request.
The proper fix is to stop relying on visitors at all and let the server call WP-Cron on a fixed timer.
Moving WP-Cron to a real server timer
This takes two changes, and you need both. Doing only the first one means nothing runs at all.
- Turn off the visitor trigger. Open
wp-config.phpand add this line above the comment that says "That's all, stop editing":define( 'DISABLE_WP_CRON', true );. WordPress will stop checking the queue on page loads. - Add a server cron job. In cPanel, open Cron Jobs. Set it to run every 5 minutes and use this command, with your own domain:
wget -q -O - https://yourguild.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1. Plesk calls this Scheduled Tasks; pick "Fetch a URL" and paste the address. If your host offers WP-CLI, itscron event runcommand with the due-now flag and the path to your install is cleaner, since it does not go through the web server. - Pick the interval sensibly. Every 5 minutes suits most fan sites. Every minute is fine on a VPS but some shared hosts limit you to 15 minutes or flag frequent jobs as abuse. Check your host's rules first.
- Test it. Schedule a dummy draft for 10 minutes from now. Watch WP Crontrol. The publish event should leave the list within one interval of its time.
- Write it down. Add a note in your team's admin doc saying cron runs from the server. The next volunteer who migrates the site will otherwise forget the server job, and scheduled posts will silently stop on the new host.
If your host has no cron panel at all, which happens on some very cheap plans, a free external pinging service can hit the same URL every few minutes. It is less reliable, and I would treat it as a reason to look at a better host.
Heavy tasks: give them their own slot
Once cron runs from the server, you can see which tasks hog it. Backup plugins and image optimisers are the usual offenders. On one wiki I helped with, a nightly full backup took nine minutes and pushed the patch notes post behind it. The fix was to move the backup to 04:30 in the plugin's settings and keep it well clear of the times we schedule content. If your database has grown huge from logs and transients, cleaning it shortens these runs too; see the walkthrough on database cleanup for a busy gaming fan site.
Email is the other quiet victim. Plugins that queue newsletters or notification emails send them through cron. If those mails never arrive even after this fix, the problem is delivery, not timing.
FAQ
Is it safe to set DISABLE_WP_CRON to true?
Yes, as long as a server cron job calls wp-cron.php on a schedule. Without that job, nothing timed will run at all, including updates checks and backups.
How often should a server cron job call WP-Cron?
Every 5 minutes works for most community sites. Use every minute only if you schedule posts to the exact minute and your host allows it.
Why does my post say Missed schedule even with traffic?
Usually full-page caching, a blocked loopback request, or a crashing plugin holding the cron lock. Site Health and WP Crontrol will show which one.
Do I still need a missed schedule plugin after this?
No. With a server timer in place, those plugins add nothing and can be removed.
More in WordPress
WordPress
How to Increase the WordPress Max Upload Size Safely
You try to upload a 40 MB match replay or a mod pack to your guild site and WordPress stops you with "The uploaded file exceeds...
WordPress
How to Migrate WordPress to a New Host Without Downtime
Your current host is slow, expensive or about to double its renewal price, and you want out.
WordPress
How to Set Up WordPress SMTP So Site Emails Arrive
A new member signs up for your guild site, waits for the welcome email, and nothing arrives.