Cyford Technologies LLC - Home | Atlanta I.T. Solutions

5 Website Development Tips To Boost Your Business Growth Exponentially


I don’t know about you, but I wake up every morning with at least 10 emails that I didn’t have when I went to sleep. While most people probably know that these emails aren’t being sent manually by some sleep-deprived, coffee-fuelled intern, many people don’t understand the ins and outs of the systems that automate tasks such as sending email.

(Image: Don Schuetze)

That’s where cron and WordPress Cron come into play. But they can be used for far more than filling inboxes to the brim. Before we dive into the specifics of both, here is a quick breakdown of the topics we’ll cover below:

  • What is cron and how does WordPress fit into it?
  • Introducing WordPress Cron
  • Limitations of WordPress Cron (and solutions to fix ’em)
  • What tasks is WordPress Cron used for?
  • How does WordPress execute scheduled tasks?
  • How to schedule tasks through WordPress Cron
  • Tips for developing with WordPress Cron
  • Popular plugins that use WordPress Cron

Still interested? Let’s get to it.

What Is Cron And How Does WordPress Fit Into It?

Cron is a system originally built for UNIX that enables users to execute commands, programs and other actions at specified times. As Wikipedia so eloquently puts it, “Cron is a time-based job scheduler.”

Basically, what that means is you can schedule an action to take place at a specific time, without having to manually execute code at that time. But how does this relate to your website — particularly, your WordPress website? Setting up your WordPress website to use the UNIX cron system built into your server’s operating system is possible; however, it can be difficult for two main reasons:

  1. Your host might not permit you to set up cron for security reasons.
  2. Different servers might require cron to be set up in different ways, which would require familiarity with a wide variety of systems.

If the WordPress team couldn’t rely on using each server’s cron, then how did they schedule tasks to be performed? They built WordPress Cron.

Introducing WordPress Cron

WordPress Cron is what many people refer to as a “pseudo-cron system.” The difference is in how UNIX cron and WordPress Cron take action. A typical UNIX cron system runs in this order:

  1. A time tied to an action occurs.
  2. Cron runs the action tied to that time.

With WordPress Cron, it works a little differently:

  1. A visitor comes to any page on your WordPress website.
  2. WordPress Cron checks each cron event to see whether the scheduled time has passed.
  3. If the scheduled time for that event has passed, then WordPress Cron executes any actions tied to that event.

Limitations Of WordPress Cron (And Solutions To Fix ’Em)

You may be wondering, “What happens if no one visits my website at all? Does WordPress Cron not run?” The biggest limitation of WordPress Cron stems from its inability to run without visitors. This leads to a few potential issues.

WordPress Cron Is Imprecise (Zero Visits = Zero Cron Runs)

If you’ve scheduled an email to be sent at 2:00 pm on Monday, then the email likely wouldn’t be sent precisely at that time, unless your website received a visit at exactly 2:00 pm. Instead, the email would be sent at the time of the first visit after 2:00 pm.

In most cases, this has little impact. But what if the email was a reminder for an event the next day, Tuesday? If the next visitor came on Tuesday night, then the email would likely serve no benefit, and could possibly confuse visitors.

So, consider the impact of no visits. If a website gets no traffic at all, then WordPress Cron will never run.

The solution is to create a more precise cron system.

If your website requires the timing to be exact, you could follow one of two methods. You could set up your server’s cron to hit wp-cron.php at a regular interval by following the instructions outlined in Harish Chouhan’s article on Wptuts+. If this seems overly complicated, you could use a tool such as Pingdom to trigger an HTTP request directly to wp-cron.php.

Running Heavy Processes Could Slow Down Your Website

Similar to running any heavy process on page load, WordPress Cron could slow down your website significantly for the visitor who triggers a heavy process tied to a scheduled event.

The solution is to keep WordPress Cron actions simple.

Especially if you run actions frequently, keep the actions tied to scheduled cron events as simple as possible. Every extra ounce of complexity will hinder the performance for your end users.

What Tasks Is WordPress Cron Used For?

We’ve covered what WordPress Cron is and what its limitations are. Now it’s time to discuss what it’s actually used for. WordPress Cron can be employed to schedule two types of hooks:

  • those to execute at a regular, repeating interval;
  • those to execute only once at a fixed time.

Examples of Tasks Scheduled at a Regular, Repeating Interval

WordPress’ core and a number of plugins use WordPress Cron to execute the following tasks at regular, repeating intervals:

  • backing up the website,
  • checking the WordPress version to ensure it’s up to date,
  • checking for updates to plugins and themes,
  • optimizing the database to improve performance.

Examples of Tasks Scheduled to Run Only Once at a Fixed Time

Single events that occur only once are used for actions such as:

  • publishing a blog post at a specific time,
  • sending an email at a specific time.

How Does WordPress Execute Scheduled Tasks?

Before jumping into how to schedule your own events, it might be helpful to understand how WordPress Cron operates. WordPress Cron runs using two files:

  • /wp-includes/cron.php
    This file contains the entire WordPress Cron API and the functions you’ll need to schedule events.
  • /wp-cron.php
    This file actually executes WordPress Cron and calls the hooks attached to the scheduled events. This file is loaded through the spawn_cron() function in cron.php.

We’ve got the files now, but what happens when a WordPress page loads? We’ll walk through the process here together (but it’s worth having a solid understanding of hooks and filters before going through it):

  1. A visitor requests a page on your website.
  2. In /wp-includes/default-filters.php, WordPress hooks the wp_cron() function to the init action.
  3. When the init action occurs in /wp-settings.php, wp_cron() runs.
  4. The wp_cron() function ensures that WordPress Cron is not disabled and that the earliest scheduled cron event has passed its execution time.
  5. If it has passed its execution time, then spawn_cron() runs and first checks whether we’re already carrying out cron and, if so, doesn’t run it again.
     if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )   return; 
  6. Starting on line 247 of cron.php, spawn_cron() loads wp-cron.php through the HTTP request. (Using wp_remote_post() to load wp-cron.php doesn’t prevent the remainder of the page from loading for the visitor.)
     $cron_request = apply_filters( 'cron_request', array( 	'url' => site_url( 'wp-cron.php?doing_wp_cron=' . $doing_wp_cron ), 	'key' => $doing_wp_cron, 	'args' => array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) ) );  wp_remote_post( $cron_request['url'], $cron_request['args'] ); 
  7. The wp-cron.php file loads and loops through all of the scheduled cron events, doing the following:
    • Line 85
      If the event is on a recurring schedule, then WordPress runs wp_reschedule_event() to schedule the next occurrence of this event.
    • Line 90
      WordPress unschedules the current event, using wp_unschedule_event(), so that it doesn’t run again in the future.
    • Line 92
      WordPress runs all of the functions tied to the hook provided in the cron event, including all of the actions that were scheduled to run at this second or prior to this second, using do_action_ref_array().
     foreach ( $crons as $timestamp => $cronhooks ) { 	if ( $timestamp > $gmt_time ) 		break;  	foreach ( $cronhooks as $hook => $keys ) {  		foreach ( $keys as $k => $v ) {  			$schedule = $v['schedule'];  			if ( $schedule != false ) { 				$new_args = array($timestamp, $schedule, $hook, $v['args']); 				call_user_func_array('wp_reschedule_event', $new_args); 			}  			wp_unschedule_event( $timestamp, $hook, $v['args'] );   			do_action_ref_array( $hook, $v['args'] );  			// If the hook ran too long and another cron process stole the lock, quit. 			if ( _get_cron_lock() != $doing_wp_cron ) 				return; 		} 	} } 

As is the case with a lot of the WordPress source code, the process is organized in a way that makes it fairly easy to follow. I encourage you to look at the code yourself in both cron.php and wp-cron.php to learn more.

How To Schedule Tasks Through WordPress Cron?

If you’ve made it this far, then we can finally turn our attention to how to use WordPress Cron in our own plugins.

Create Recurring Events in WordPress Cron

Creating an event that repeats on a fixed schedule is done using wp_schedule_event( $timestamp, $recurrence, $hook, $args ), in which the following four parameters are used:

  • $timestamp (required: integer)
    This is the time when you want the event to occur. This must be in a UNIX timestamp and must be in GMT. If you’re using local time, then convert it to GMT first or else the event won’t fire at the correct time.
  • $recurrence (required: string)
    This is how often the event should occur. The default options are hourly, twicedaily or daily. You can also add your own options, which we’ll touch on shortly.
  • $hook (required: string)
    This is the name of the action hook you’d like to execute. The advantage of calling an action hook instead of a function directly is that you can tie multiple functions to one hook using add_action().
  • $args (optional: array)
    These are any arguments you want to pass to the hooked function or functions. This could be a post ID, a backup schedule ID, a user ID or any other information you’ll use in your functions.

Let’s say we built a plugin that backs up the WordPress database once a day. Here’s what the code would look like if we were to schedule the backup with WordPress Cron:

 //On plugin activation schedule our daily database backup  register_activation_hook( __FILE__, 'wi_create_daily_backup_schedule' ); function wi_create_daily_backup_schedule(){   //Use wp_next_scheduled to check if the event is already scheduled   $timestamp = wp_next_scheduled( 'wi_create_daily_backup' );    //If $timestamp == false schedule daily backups since it hasn't been done previously   if( $timestamp == false ){     //Schedule the event for right now, then to repeat daily using the hook 'wi_create_daily_backup'     wp_schedule_event( time(), 'daily', 'wi_create_daily_backup' );   } }  //Hook our function , wi_create_backup(), into the action wi_create_daily_backup add_action( 'wi_create_daily_backup', 'wi_create_backup' ); function wi_create_backup(){   //Run code to create backup. } 

To start, we hook wi_create_daily_backup_schedule() to register_activation_hook() so that our cron backup event will be added immediately when the plugin is activated. In wi_create_daily_backup_schedule(), we do two things:

  1. We use wp_next_scheduled() to check whether our cron event has already been created. And wp_next_scheduled() will either return a timestamp of the next scheduled event for a hook (wi_create_daily_backup) or return false, telling us that our cron event is not scheduled.
  2. If $timestamp == false, then we schedule our cron event for daily backups. We schedule the first backup to happen immediately by using the PHP function time(), and then we pass the daily recurrence schedule and our wi_create_daily_backup hook.

After creating the scheduled event, all that’s left to do is tie our backup function to the wi_create_backup action. We use add_action( 'wi_create_daily_backup', 'wi_create_backup' ) to hook our function. Then, we write our wi_create_backup() function to generate a backup of the website.

Adding a New WordPress Cron Schedule

As I mentioned when discussing recurring events, the default options for recurring schedules are hourly, twicedaily and daily. But what if, instead of running our backup daily, we wanted to run it weekly? WordPress makes a weekly schedule easy with the cron_schedules filter. To make the schedule weekly, you’d write the following code in your plugin:

 add_filter( 'cron_schedules', 'wi_add_weekly_schedule' );  function wi_add_weekly_schedule( $schedules ) { 	$schedules['weekly'] = array( 		'interval' => 7 * 24 * 60 * 60, //7 days * 24 hours * 60 minutes * 60 seconds 		'display' => __( 'Once Weekly', 'my-plugin-domain' ) 	); 	/* 	You could add another schedule by creating an additional array element 	$schedules['biweekly'] = array( 		'interval' => 7 * 24 * 60 * 60 * 2 		'display' => __( 'Every Other Week', 'my-plugin-domain' ) 	);   */  	return $schedules; } 

The $schedules array is passed into our function and enables us to add the weekly key with the desired schedule. For the interval key, we must include the number of seconds we’d like between the times this cron event runs. To run once weekly, we calculate 7 days × 24 hours × 60 minutes × 60 seconds to give us the total number of seconds in a week. Then, we create the display name, “Once Weekly,” in case others need to read a description of our schedule.

Don’t forget to localize your description using __(), so that it can be translated later. If you’re interested in adding more than one schedule, simply create a new array key within $schedules, such as $schedules[‘biweekly’], and add the interval and description. To complete our function, we return the $schedules array, including our new schedule.

Looking at the previous example of our backup schedule, if we wanted it to run weekly, we’d simply take this:

 wp_schedule_event( time(), 'daily', 'wi_create_daily_backup' ); 

And we’d change it to this, using the new weekly schedule we created:

 wp_schedule_event( time(), 'weekly', 'wi_create_daily_backup' ); 

Now, our backup will run once a week.

Removing Scheduled Cron Events

Returning to our backup plugin example, what we’ve done so far does have one problem. We haven’t removed our scheduled backup event upon deactivation of the plugin. This won’t actually cause an error when the event executes daily, but it will force cron to run, possibly slowing down the website ever so slightly. Removing our scheduled event is easy.

 register_deactivation_hook( __FILE__, 'wi_remove_daily_backup_schedule' ); function wi_remove_daily_backup_schedule(){   wp_clear_scheduled_hook( 'wi_create_daily_backup' ); } 

Very much like we did on activation, we hook a function, wi_remove_daily_backup_schedule(), to the deactivation of our plugin. We pass the event hook wi_create_daily_backup to wp_clear_scheduled_hook(), and then the schedule will be removed from WordPress Cron.

It’s worth noting that wp_clear_scheduled_hook() will remove all events associated with that hook. If you want to remove only one event, then use wp_unschedule_event() instead; this function requires that you pass in the timestamp of the event you wish to remove.

Create a Single Event in WordPress Cron

Creating a single event to occur at a specified time is sometimes required. To create a single event in WordPress Cron, we must use wp_schedule_single_event( $timestamp, $hook, $args ). The parameters here are exactly the same as wp_schedule_event(), except that they don’t include the $recurrence parameter, thus allowing the event to occur only once.

Let’s say we want to send a reminder email for a volunteer activity that will happen in the future. You can use this code directly inside a function run when the post about the volunteer activity is saved in WordPress’ admin section.

 //Convert start time from local time to GMT since WP Cron sends based on GMT $start_time_gmt = strtotime( get_gmt_from_date( date( 'Y-m-d H:i:s', $start_time ) ) . ' GMT' );  //Set reminder time for three days before event start time $time_prior_event = 3 * 24 * 60 * 60; //3 days * 24 hours * 60 minutes * 60 seconds $reminder_time = $start_time_gmt - $time_prior_event;  //Remove existing cron event for this post if one exists //We pass $post_id because cron event arguments are required to remove the scheduled event wp_clear_scheduled_hook( 'wi_send_reminder_email', array( $post_id ) );  //Schedule the reminder wp_schedule_single_event( $reminder_time, 'wi_send_reminder_email', array( $post_id ) ); //... 

In this code, a number of important steps are happening. First, if the time of the volunteer activity is stored in a variable in local time, then we have to convert it to GMT, because WordPress Cron is not run using local time. Once converted to the variable $start_time_gmt, we set $reminder_time to the volunteer activity’s start time minus the number of seconds prior to the event that we wish to send the email.

We then remove any scheduled events for this hook and post to avoid scheduling our event multiple times when the post is saved. Remember that you must pass an array, including the same arguments that you used to create the scheduled event, in order to remove it. In this case, we’re passing the post’s ID. This makes sense, after all. You want to remove the scheduled email reminder not for every volunteer activity, only for the one that the user is saving.

Once we’ve created the reminder time and cleared any previously scheduled events, we create the new event using wp_schedule_single_event(), with the timestamp $reminder_time. We also pass in the $post_id for this particular post so that we can include custom information in our email, such as the post’s title, the time of the activity, the description of the activity and any other information.

To actually send the email when the cron event occurs, we hook the function that we want to execute when the event fires to wi_send_reminder_email.

 //Hook our function, wi_send_event_reminder_email(), into the action wi_send_reminder_email add_action( 'wi_send_reminder_email', 'wi_send_event_reminder_email' ); function wi_send_event_reminder_email( $post_id ){   //Run code to send reminder email, customizing based on the post id } 

Tips For Developing With WordPress Cron

When you code with WordPress Cron, a couple of tools in particular could really help your development process.

WP Crontrol

WP Crontrol is a WordPress plugin that helps you develop using the WordPress Cron API. It displays all scheduled cron events, enables you to edit, run or delete cron events using a GUI and also enables you to see all available cron schedules.

The admin interface of WP Crontrol.

I highly recommend WP Control if you plan to use the WordPress Cron API in a plugin.

IDE Debugger

If you develop plugins using an integrated development environment (IDE) instead of a basic text editor, then a debugger can be a hugely helpful resource for reviewing the array of cron events and creating new events. If you’re not already using an IDE, two of the most popular are Eclipse and NetBeans, but plenty more are out there to choose from.

Examples Of WordPress Cron Used In Popular Plugins

The WordPress Cron API is used often in popular plugins across the WordPress platform. To give you a feel for its use, I’ll cover how two rather popular plugins employ the API.


Akismet is the leading spam-prevention tool for WordPress. At the time of writing, it’s been downloaded over 14 million times.

Akismet uses the WordPress Cron API for a number of purposes, including:

  • Rechecking in the future whether a comment is spam in the event that Akismet’s servers are unreachable during a check;
  • Rechecking an Akismet API key if the plugin is unable to verify at that moment due to an unreachable server;
  • Deleting old spam comments on a regular basis;

To delete old spam comments, Akismet creates a daily event and deletes comments over a certain age every day.

 if ( function_exists('wp_next_scheduled') && function_exists('wp_schedule_event') ) { 	// WP 2.1+: delete old comments daily 	if ( !wp_next_scheduled('akismet_scheduled_delete') ) 		wp_schedule_event(time(), 'daily', 'akismet_scheduled_delete'); } 

Broken Link Checker

Broken Link Checker is a WordPress plugin that checks your entire website for broken links. It uses WordPress Cron for a number of regular activities, including:

  • Checking new links hourly to ensure they’re not broken,
  • Emailing notifications about broken links on the website,
  • Completing database maintenance every two months,
  • Updating news about the plugin every day,

Broken Link Checker creates each of these schedules through one function, setup_cron_events().

 /** * Install or uninstall the plugin's Cron events based on current settings. * * @uses wsBrokenLinkChecker::$conf Uses $conf->options to determine if events need to be (un)installed.   * * @return void */ function setup_cron_events(){ 	//Link monitor 	if ( $this->conf->options['run_via_cron'] ){ 		if (!wp_next_scheduled('blc_cron_check_links')) { 			wp_schedule_event( time(), 'hourly', 'blc_cron_check_links' ); 		} 	} else { 		wp_clear_scheduled_hook('blc_cron_check_links'); 	}  	//Email notifications about broken links 	if ( $this->conf->options['send_email_notifications'] || $this->conf->options['send_authors_email_notifications'] ){ 		if ( !wp_next_scheduled('blc_cron_email_notifications') ){ 			wp_schedule_event(time(), $this->conf->options['notification_schedule'], 'blc_cron_email_notifications'); 		} 	} else { 		wp_clear_scheduled_hook('blc_cron_email_notifications'); 	}  	//Run database maintenance every two weeks or so 	if ( !wp_next_scheduled('blc_cron_database_maintenance') ){ 		wp_schedule_event(time(), 'bimonthly', 'blc_cron_database_maintenance'); 	}  	//Check for news notices related to this plugin 	if ( !wp_next_scheduled('blc_cron_check_news') ){ 		wp_schedule_event(time(), 'daily', 'blc_cron_check_news'); 	} } 


By now, you’re probably croned out, but I’m glad you stuck with me. You should now have a solid understanding of what WordPress Cron is, how it works and how you can use it to automate different features and functionality in your plugin.

If you have experience with WordPress Cron or have just started playing around, I’d love to hear from you in the comments. What issues have you run into? What are you using it for? Any tips for speeding up development? Do you know of any plugins that use the WordPress Cron API in an innovative way?

(al ea)

© Jonathan Goldford for Smashing Magazine, 2013.


Read more

Published on: Mar 03, 2021

Categories: Web Development

    No Comments yet! Be the first one to write.

    Leave a Reply

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