My WordPress has been acting strange for a while, missing scheduled posts and other general weirdness. I eventually traced the problem to a file called wp-cron.php. Here’s how I automated wp-cron.php to improve WordPress speed and reliability.
Note: My fix involves running commands directly. If you don’t have shell access to your server, you’ll need to use another method. There are lots of other guides out there showing how to do something similar with plugins. But since I host my own server and have shell access, this way is lower overhead.
What cron is
Cron is the Unix task scheduler. Linux inherited it, being an open source clone of Unix.
The file wp-cron.php is the WordPress equivalent. It normally runs when someone visits your site. That’s not ideal, as it means you either run it too frequently, or too infrequently, depending on how much traffic you get. If you install a caching plugin to keep up with heavy traffic, it means it only runs when someone visits an uncached page. So in my case, sometimes my site would go for 5 hours between wp-cron.php runs, since someone would have to visit an obscure page for it to hit.
This causes problems like scheduled posts missing their schedule and either posting late, or not at all.
The other reason it’s not ideal is under heavy traffic, wp-cron.php is running every time someone visits, which gives the site one more thing to do before serving up a page. This increases overhead.When serving up cached pages, my site’s CPU usage was around 1-2 percent. But it rocketed to 100% if I was editing a blog post and someone else was visiting obscure pages at the same time. That’s with a 4-core, 3.8 GHz CPU all to myself. I couldn’t use Yoast internal linking, which is something I need, with 20 years of content here.
Yoast support told me there was something wrong with my site but couldn’t tell me where to start troubleshooting, so I’ll document the fix here. At least it’s something. And it will speed up your site even if it doesn’t fully solve your specific problem.
Why does WordPress work this way? Ease of use. The idea is you shouldn’t need to be a professional Unix sysadmin to blog. But if you’re going to be a high traffic site, at least having some mad Unix skilz helps. This is one of those cases.
Why not disable caching?
I could have solved the problem by disabling caching, but that would have slowed the site down even more. If you serve up a million pages a year, or have ambitions to, you need caching, or a crazy fast and expensive CPU. I like being able to use affordable hardware, as I’m not a huge operation. I like Simple Cache because it works well and even its advanced mode only has three options. Simple mode is just on and off. But to use any caching plugin effectively, you also need to fix wp-cron.php.
If nothing else, a slow site is terrible for SEO. Operating a moderately high traffic site requires quite a bit of balance.
Migrating wp-cron.php to the OS crontab
First, find out what user account your webserver runs under. You can use this command:
sudo ps aux | egrep '([a|A]pache|[h|H]ttpd)'
Pro tip: It’s probably www-data, but don’t take my word for it. Run the command and verify.
Next run this command and add this line to the end of the file:
sudo EDITOR=nano crontab -e -u www-data
Substitute the name of the account if yours is something other than www-data. Substitute the name of your preferred editor if it’s something other than nano.
*/10 * * * * php /var/www/wordpress/wp-cron.php > /dev/null 2>&1
Save the file by hitting CTRL-O followed by CTRL-X.
Last step, I promise. Edit your wp-config.php file. If you don’t know its full path, run this command:
find / -name wp-config.php
Next, edit the file, substituting the path for my example below:
sudo nano /var/www/wordpress/wp-config.php
Scroll to the end, look for a line that reads:
/* That’s all, stop editing! Happy blogging. */
And then add this line above it:
Save the file by hitting CTRL-O followed by CTRL-X. And that’s it.
With this change, my CPU usage dropped a good 75% when I’m editing WordPress content. Which is a very good thing.