In the continuing effort of learning by doing, running my own servers has been a real eye opener. Today I learned something new. WordPress cron is not really cron.
Even a self hosted WordPress instance still needs things to happen at a certain time, or interval. So the programmers of WordPress made a cron like function, which they call wp-cron to handle everything in the background. I wouldn’t even know about it, except that I received a warning message about a missed schedule for my WordPress blog.
From my limited understanding, the WordPress instance runs a php script, called wp-cron.php, to do odds and ends that need done behind the scene. However, unlike a system cron job, it can’t call itself unless someone visits your website. The act of calling your page up by viewers triggers the wp-cron jobs to run. This presents two main problems.
The first problem is that your wp-cron jobs only run when triggered and meet the time criteria, so if you have a wp-cron job that is supposed to run at 6 am, such as posting your scheduled post, then it will do so anytime after 6 am that someone visits your website, thus meeting both criteria. But if your website is slow like mine, you may not get a visitor for a few hours, and then at 8:43, when that next visitor stops by, your wp-cron job runs, 2 hours and 43 minutes late.
The second issue with this setup is that the wp-cron job runs when that user showed up at 8:43, the moment they called your homepage, and thus slowing down the server from filling that request until the job is done. This could cause them to actually have to wait for the page to load, or perhaps, in rare cases, not get the page at all.
Thus, I decided to try out the system cron scheduled method of calling wp-cron. The WordPress documentation was pretty clear, which you can read here. As the root user, I ran:
# crontab -u www-data -e
And appended this line at the end of my crontab:
*/15 * * * * wget --delete-after https://alaskalinuxuser3.ddns.net/wp-cron.php
And then disabled wp-cron from being loaded each website visit by adding these lines to my WordPress wp-config.php file:
/** Stop wp-cron from running every page load, because cron will run it. */
define('DISABLE_WP_CRON', true);
Now instead of holding up my visitors and on slow days missing scheduled events, my system cron job will execute the wp-cron scheduler every 15 minutes on it’s own. I’m not sure about the timing, to be honest I think I could stretch it out to much, much longer, perhaps even a few times a day, but I don’t think this will pose an unnecessary load on my server. From what I understand, it will only call wp-cron, which will check if there are any scheduled events. If none are scheduled, then it will do nothing, I think.
Linux – keep it simple.
I think when php was first introduced it was offered as a generic scripting language, suitable for use for sysadmins. It didn’t have to be executed only on the web.
I’m glad you learned and resolved this wp-cron problem. And you know, one alternative to needing this cron job is to get popular enough to have round-the-clock views, so go work on that!