Using real cron for WordPress with WP CLI

For WordPress site owners wishing to use real cron via a crontab job, it’s fairly common to see advice to use curl to request the site’s wp-cron.php file on a regular basis.

In the days before the WordPress CLI (WP-CLI), using the wp-cron.php file was the only technique available to site owners wishing to use real cron events.

As WordPress doesn’t use real cron with wp-cron.php, using the file has some limitations. It runs each event as request to your web server which means long running tasks may time out before they are complete.

More problematically, if your site is behind a username and password, using wp-cron.php may fail to run in certain server configurations.

Configuring WordPress for real cron

To configure WordPress to use real cron jobs requires disabling the faux cron jobs WordPress uses natively. This is done by adding a directive to the wp-config.php file:

define( 'DISABLE_WP_CRON', true );

Disabling WordPress’s native cron instructs the Site Health Check feature to relax some of the rules around when a cron job is considered late or failed. A cron job is considered late if it hasn’t run within 15 minutes of the scheduled time, and failed if it hasn’t run within one hour of the scheduled time.

I recommend you configure your server to run real cron tasks every ten minutes to ensure you don’t get incorrect reports of errors in the WordPress dashboard.

Setting up a cron job differs depending on your web hosting provider, there is no one size fits all instruction available. For popular web hosting dashboards view cPanel’s cron job documentation or Plesk’s cron job documentation.

The modern approach

For the uninitiated, WP-CLI allows site owners to manipulate WordPress via the command line: you can modify posts, for example, but importantly you can also run cron events.

Many hosting providers include WP-CLI as a standard feature, especially those providing specialist WordPress hosting. This is a requirement for the modern approach to running cron.

The simplest approach is to run the following command as the cron job.

cd /path/to/site;
wp cron event run --due-now

Allowing for long running tasks

If you have long running cron events in WordPress, the safest approach to running these is to run each task in its own process. It also prevents a fatal error in one of your events from preventing other events from running.

On the downside, the command is a little more complicated. The script becomes:

cd /path/to/site;
for hook in $(wp cron event list --next_run_relative=now --fields=hook --format=ids); 
  do wp cron event run "$hook";
done;

The portion of the script wp cron event list --next_run_relative=now --fields=hook --format=ids gets a list of events ready to be run and returns them in a space separated format. On a basic install of WordPress, it might return wp_version_check wp_update_plugins wp_update_themes if those three tasks are ready to be run.

The remainder of the script is a loop calling the wp cron event run command for each of those tasks individually.

Confirming it’s all working

The important final step is to make sure it’s all working as expected. I mentioned above the Site Health pages within WordPress. One of the tests run is to ensure that scheduled events are still running.

By default, WordPress includes a task that runs every hour. As mentioned above, if a task is more than an hour late the Site Health report will considered it as failed.

After setting up your site to use real cron jobs, fill in a couple of hours (bike ride, walk the dog, make yourself a fancy dinner, whatever) and log in to your site’s dashboard and visit the Site Health page accessible to administrators in the Tools menu.

If everything is running as expected, in the passed tests section of the report you will see scheduled events are running. If that’s in the list of passed tests, you can rest easy knowing your site is using real cron jobs and everything is just dandy.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.