For some reason that no one in the WordPress community has been able to figure out, scheduled posts sometimes fail to appear.
This is shown as “Missed Schedule” in WordPress. Unfortunately, once a schedule is missed, the post goes into limbo. The admin has to go in and manually publish or reschedule the post.
On LowEndBox, these tend to happen once every few months. We just had one last week, and when I went to mention it in a LowEndTalk thread, I found it had never been published. There’s no warning sent.
What causes this? Probably some kind of perfect storm.
How WordPress’s Fake Cron Works
WordPress does not have a running daemon, so there’s no “crond” running in the background checking what’s due. Instead, whenever someone visits your site, WordPress checks if an article is due and quickly publishes it. This makes sense – sort of a “if a tree falls in the forest and no one is around, does it make a sound” kind of scenario. If you have an article scheduled to appear at 1pm, and no one visits until 3pm, does it matter? It’ll show up when that first 3pm visitor comes around, time-stamped 1pm.
How WordPress’s Fake Cron Sometimes Doesn’t Work
In my research, the reason this sometimes fails is not entirely clear. My googling lays the blame at several possible culprits:
- Caching
- Lack of processing resources
- Interfering plugins
- Host OS limitations
…or a perfect storm of all of these. In LowEndBox’s experience, it’s not consistent.
My guess is in that our case, it’s all the collateral actions that happen when we publish. If you have a completely generic WordPress site, moving a post from “scheduled” to “published” is little more than updating a field in the database. But in our case, it also means updating the sitemap, queueing various social network notifications, etc. I suspect that when a visitor comes and WordPress goes to do all of that, something times out and the publication never happens.
How to Fix It
One option is to install a plugin designed to address this problem, but who needs more WP plugins? They do exist. WP Crontrol is one, but I haven’t really investigated them.
A better solution is to ditch WP’s fake cron and run a job in real cron. This takes two steps:
(1) Disable WordPress cron. Edit your wp-config.php file and add this:
define('DISABLE_WP_CRON', true);
Reload your site (i.e., visit it in your web browser) to make sure you didn’t typo anything.
(2) Login to your WordPress box and edit the web user’s crontab as follows:
*/5 * * * * /bin/wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Replace ‘example.com’ with your own domain.
This job will fire every 5 minutes, and will publish anything that is due/overdue.
That specific syntax will sent any errors to the bit bucket (/dev/null). If you want to receive them, modify as follows:
MAILTO=you@example.com
*/5 * * * * /bin/wget -q -O - https://example.com/wp-cron.php?doing_wp_cron
Cron will send any output to the address specified in the MAILTO line
Don’t do this
Use wp cli if running in cron or php binary to run the file
Wget is identical to faking a visitor every 5 min and likely blocked by cloudflare etc
We use cloudflare and it works fine for us.