For a long time I used the WP Cron Control plugin and an associated cron job to make sure that scheduled actions on my WordPress multisite instance were executed properly. (You should never rely on event execution that is triggered by visits to your website, the WordPress default, IMHO.) But after the upgrade to WordPress 5.4 I noticed that some of my scheduled events in WordPress were not firing on time, sometimes delayed by 10-20 minutes. I did some troubleshooting and got as far as suspecting a weird interaction between that plugin and WordPress 5.4, but never got to the bottom of it.
When I reluctantly went in search of a new solution, I decided to try using WP CLI cron commands, executed via my server’s own cron service. Ryan Hellyer provided most of what I needed in this helpful post, and I extended it a bit for my own purposes.
Here’s the resulting script that I use:
#!/bin/bash # This script runs all due events on every WordPress site in a Multisite install, using WP CLI. # To be run by the "www-data" user every minute or so. # # Thanks https://geek.hellyer.kiwi/2017/01/29/using-wp-cli-run-cron-jobs-multisite-networks/ PATH_TO_WORDPRESS="/path/to/wordpress" DEBUG=false DEBUG_LOG=/var/log/wp-cron if [ "$DEBUG" = true ]; then echo $(date -u) "Running WP Cron for all sites." >> $DEBUG_LOG fi for URL in = $(wp site list --field=url --path="/path/to/wordpress" --deleted=0 --archived=0) do if [[ $URL == "http"* ]]; then if [ "$DEBUG" = true ]; then echo $(date -u) "Running WP Cron for $URL:" >> $DEBUG_LOG wp cron event run --due-now --url="$URL" --path="$PATH_TO_WORDPRESS" >> $DEBUG_LOG else wp cron event run --quiet --due-now --url="$URL" --path="$PATH_TO_WORDPRESS" fi fi done
Then, in my system crontab:
# Run WordPress Cron For All Sites */2 * * * * www-data /bin/bash /path/to/bin/run-wp-cli-cron-for-sites.bash
Yes, I run cron every 2 minutes; there are some sites I operate that require very precise execution times in order to be useful. One implication is that this solution does not scale up very well; if the total execution time of all cron jobs across all sites exceeds 2 minutes, I could quickly run into situations where duplicate jobs are running trying to do the same thing, and that could be bad for performance or worse.
Thanks for the code. This is helpful!
I have a small tweak to make debugging easier:
if [ $1 == "--debug" ]; then
DEBUG=true
else
DEBUG=false
fi
Then if you want to debug, just append –debug when you call the script:
$ /path/to/bin/run-wp-cli-cron-for-sites.bash --debug