Skip to content

Scheduling WordPress Tasks and WP-CLI Commands to Run from System Cron

WordPress comes with a built-in task scheduler called WP-Cron. This is the part of core that regularly checks to see if WordPress itself needs updating, or if any of your plugins and themes have updates available.

Named after the Unix Cron service that runs various system tasks at specified intervals, WordPress’ implementation isn’t a true cron service though – there is no guarantee that your task will run exactly when you have it scheduled to. This is because WP-Cron is triggered when a page on your site is viewed. The upside to this is that you don’t have to fiddle with cron jobs to get WordPress’ tasks running, it’s just part of the web application. The downside though: if your site has occasional traffic, tasks will only be run when the next page visit happens.

If you want WordPress tasks to run reliably, you can disable the built-in trigger to run cron jobs, and instead configure your server’s system cron service to trigger the WordPress scheduler.

Prerequisites

To implement the solutions shown below, you will need to be able to modify your system cron file. Your ability to do so will depend on your web host’s setup. For example, some implementations of cPanel allow you to add cron jobs to the server.

The examples below assume that you have SSH access to your server, and can run commands from the terminal.

Trigger WP-Cron from System Cron

The first thing you’ll want to do to disable the built-in cron service. To do this, add the following line to your wp-config.php file.

define('DISABLE_WP_CRON', true);

Next, you’ll need to add a task to your system’s crontab telling it to make a call to WordPress’ cron service. To do this, run the following command on your web server:

crontab -e

This will open the crontab file. Next, you need to add a line to this file that indicates what command to run and when it should run.

Every cron command is made up of 6 parts. The first five parts indicate when the command will run. The five pieces are (in order):

minutes (0 – 59)
hours (0 – 23)
day of the month (1 – 31)
month (1 – 12)
day of the week (0 – 6)

If any of these pieces are set to *, it indicates “all” for that part of the time configuration.

The last piece of the cron command is the command to be run.

An example cron configuration line looks like:

0 0 * * * wget https://example.com/wp-cron.php

This command will run wget https://example.com/wp-cron.php at midnight every day.

The wget command is used for retrieving content from the web from the command line. Since it is non-interactive, it’s perfect for command line use.

Triggering WP-CLI Commands to Run from Cron

WP-CLI, the command line tools for WordPress, is quickly becoming a prefered way (at least for me!) of automating management of WordPress sites. The idea of being able to create custom WP-CLI commands and then trigger those as cron jobs has become my preference over using the built-in WP-Cron scheduler. The main reason for this is that I can choose to run a task from the command line manually, off-schedule, if needed.

To do this, modify your crontab file (save as above) and add a scheduled task like:

0 * * * * /usr/local/bin/wp --path=/var/www/html aco-stats update

This command runs the custom command aco-stats update every hour on the hour.

Notice I had to add the –path parameter to the wp command specifying where my WordPress site is located on the server. This is because cron jobs aren’t run from the WordPress folder.

Another neat trick I’ve done with my WP-CLI commands (stolen from the built-in search-replace command) is added a –dry-run flag that will output what would happen if cron ran that command right now. It’s a handy way, if needed, of previewing what’s going to happen the next time the command runs.

Cool, right?

Both of these solutions lead to a more reliable scheduler than the built-in WP-Cron implementation.

Have fun!

2 Comments

  1. Instead of using wget, I run the php command:
    0 * * * * www-data php /var/www/my-web-site/wordpress/wp-cron.php > /dev/null 2>&1

Leave a Reply

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