As it relates to scheduling events in WordPress, there’s a lot of articles that already exist on setting up a WordPress cron job, but – and for what I believe to be a number of reasons – there’s a surprising lack of clarity around the topic.

Of course, I could be wrong – maybe I’ve just been looking in all of the wrong places.

Whatever the case may be, this is something that I’ve been dealing with in a couple of projects, and I thought I’d capture my notes here if, for no other reason, than to reference in the future.

Understanding WordPress Cron Jobs

Before actually taking a look at WordPress cron jobs, it’s important to understand exactly what a cron job is.

Simply put, a cron job is a task that is set to run at a specified interval. Generally speaking, it’s available on Linux or Unix-based system (OS X included) and, thus, most web hosts.

So if you’re looking for a way to execute a certain command several times a day, a certain time of day, a certain time of the week, month, or whatever else, then this is what you use.

What Are WordPress Cron Jobs?

For anyone who has spent time working with WordPress, then you’ve no doubt noticed the wp-cron.php file or the WordPress codex articles for <a title="wp_cron" href="http://codex.wordpress.org/Function_Reference/wp_cron" target="_blank">wp_cron</a> or <a title="wp_schedule_event" href="http://codex.wordpress.org/Function_Reference/wp_schedule_event" target="_blank">wp_schedule_event</a>.

wp_cron

As convenient as this functionality is, the best way that I know how to describe WordPress cron jobs are as faux cron jobs.

Here’s why: whenever a cron job is defined within the context of an operating system, it is scheduled to run by the operating system for that particular time regardless of if the person is at the computer or not.

After all, what would be the purpose of scheduling a job if it had to run manually?

When it comes to WordPress, you can schedule an event to happen at a certain interval, but it doesn’t operate like a classical cron job.

Instead, the event is set and scheduled and written to the database. The next time a user hits the site, the WordPress cron system will look to see if an event is scheduled and, if so, will then fire the event.

Notice the problem?

Someone has to visit the site before the event actually kicks off. So if you’ve scheduled something to happen hourly, but no one has visited your site in the last hour, then the event will never kick off.

If you have a very active site, then this isn’t a problem, but if you’re, say, building a plugin that needs to execute some code every hour, day, week, month, or whatever then using the default WordPress cron job system is simply not a good idea.

Setting Up a WordPress Cron Job

To give a real world example, here’s a scenario in which I’ve been working:

  • A user drops a CSV file into a directory
  • Every hour, the directory needs to be checked for the presence of a file
  • If a file exists, then the data needs to be imported and the file deleted; otherwise, the job can be skipped

Easy enough, right?

But here’s the challenge: If I setup a job using wp_schedule_event and no one visits the site, then nothing will actually happen until the next person visits the site.

Sad story.

Here’s what needs to happen:

  • From a code level, an algorithm for the above procedure needs to be defined
  • An actual Unix-level cron job needs to be scheduled to fire each hour

Specifically, the cron job defined at the Unix level needs to be setup such that it runs at whatever interval you like and that it mimics a user visiting the site.

Luckily, this is really easy to do.

Defining a WordPress Cron Job

To fully define a WordPress cron job, then this is what needs to happen:

  1. Disable the WP Cron System
  2. Setup your event code using `wp_schedule_event` in your plugin or in `functions.php`
  3. Define a cron job

Nothing terribly complicated – here’s code for how to handle all of the above.

1. Disable WP Cron

In your wp-config.php file, add the following line:

define('DISABLE_WP_CRON', true);

Done and done.

2. Setup Your Event Code

Note that YMMV based on whether or not you’re working with a plugin or with wp-config.php, but here’s the gist of everything that needs to happen.

1. Add Event Action

First, define a custom action for your, say, hourly event and give it the name of the function that will be fired each hour.

add_action( 'my_hourly_event',  'update_db_hourly' );

In our case, that function is update_db_hourly .

2. Define The Function

Now, define the function update_db_hourly for scheduling the event with WordPress.

If you’re working with a plugin, then you can schedule the event during the plugin’s activation (but also remember to remove the schedule when the plugin is deactivated):

public static function activate() {
    wp_schedule_event( time(), 'hourly', 'my_hourly_event' );
}

public static function deactivate() {
    wp_clear_scheduled_hook('my_hourly_event');
}

Finally, define the function that’s responsible for actually, y’know, doing the work:

public function update_db_hourly() {

    // 1. Check for a new file
    // 2. If it exists, read it, upload it, delete it
    // 3. Otherwise, do nothing

}

3. Setup The Cron Job

Most web hosts provide an interface for defining cron jobs, but not all applications are running within the context of a cPanel-based web host.

Some are simply running on an internal server or something similar where all you have is access to the command line. And considering that the cPanel is nothing more than a GUI to the command line, here’s what you need to know to define a cron job at the operating system level:

Launch the cron job file editor in your terminal using crontab -e:

crontab -e

This will bring up a seemingly empty file (if you’ve not defined any other jobs):

Empty Cron File

Next, add the following line into the cron file:

*/15 * * * * wget -q -O - http://yourdomain.com/wp-cron.php?doing_wp_cron

Of course, you’ll want to change up the domain for your own purposes.

The complete guide the cron commands and tools such as wget is outside the scope of this article, but this will trigger an event to fire every 15 minutes that will make a request to your WordPress website thus kicking off any scheduled tasks.

Not bad, right?

WordPress Cron Jobs

Overall, it’s not a terribly complicated procedure to setup but there are several gotchas that, unless you’re familiar with how the WordPress cron system works, can really cause some serious problems in your work.

Hopefully the notes above demystify a bit of how WordPress handles scheduled events and how you can force them to kick off using your hosting environment.