Skip to content
Home » Blog » Computer Science » Web Development » WordPress » wp_unschedule_hook vs wp_clear_scheduled_hook vs wp_unschedule_event: which should I use?

wp_unschedule_hook vs wp_clear_scheduled_hook vs wp_unschedule_event: which should I use?

3 minute read

WordPress helpfully offers developers two distinct methods for deleting CRON jobs, or automated events. The first one was wp_clear_scheduled_hook() that was introduced in WordPress core version 2.1.0 while wp_unschedule_hook() was introduced later in version 4.9.0. Both are useful, but there are slight differences in what they do, and that’s important to understand in order to determine which one you need to use.

When to use wp_clear_scheduled_hook

This function takes up to three (3) parameters:

  1. $hook – (string) required, the action hook of the CRON event you want to remove from the queue
  2. $args – (array) optional, the same sequential array used when creating the CRON event to add it to the queue
  3. $wp_error (boolean) optional, pass true to return the WP_Error object on failure instead of returning boolean false.

This function returns an integer indicating the number of events that were removed from the CRON queue, which includes zero if there weren’t any in the queue. If deleting any of the events from the queue failed, it’ll return either boolean false or the WP_Error object based on the third parameter.

Let’s say you have multiple posts scheduled to be published. Those events would appear in the CRON queue using the same hook of publish_future_post but with different arguments specifying which post to publish, like so:

$args = [1234]; // Sequential array with post ID as the one and only item

So in order to remove just that one CRON event, you need to pass the same exact parameter used to create it, like this:

wp_clear_scheduled_hook(
    'publish_future_post',
    array(1234)
);

If you happen to have duplicate events, events with identical hooks and arguments, then both will be deleted with this function. If you need to only delete one of those identical events, then you need to use wp_unschedule_event() which also takes the timestamp as a parameter.

When to use wp_unschedule_hook

This function takes up to two (2) parameters:

  1. $hook – (string) required, the action hook of the CRON event(s) you want to remove from the queue
  2. $wp_error (boolean) optional, pass true to return the WP_Error object on failure instead of returning boolean false.

Just like wp_clear_scheduled_hook, this function returns an integer indicating the number of events that were removed from the CRON queue, boolean false, or the WP_Error depending on what happened and whether or not you want it to return the error object.

Notice how this function doesn’t ask for arguments? That’s because it doesn’t care! This function will remove all CRON events from the queue that matches the $hook parameter regardless of its settings. So using the function like this…

wp_unschedule_hook( 'publish_future_post' );

… will wipe out all events from publishing those posts in the future.

If you’re a WordPress plugin developer, this is a must-have to add in your uninstall hook or file for your plugins that add automated CRON events.

When to use wp_unschedule_event

This function is different from wp_clear_scheduled_hook and wp_unschedule_hook in that wp_unschedule_event will only remove a single event from the CRON queue whereas the can remove more than one. That’s why this function name specifies “event” and not “hook.”

This function takes up to four (4) parameters:

  1. $timestamp (integer) required, the Unix timestamp (UTC) of the event you want to remove from the queue.
  2. $hook – (string) required, the action hook of the CRON event you want to remove from the queue
  3. $args – (array) optional, the same sequential array used when creating the CRON event to add it to the queue
  4. $wp_error (boolean) optional, pass true to return the WP_Error object on failure instead of returning boolean false.

This function returns boolean true if it was successfully removed from the CRON queue, and boolean false or the WP_Error object otherwise.

Just like wp_clear_scheduled_hook above, you need to know the parameters, but you also need to know when it is going to run next! If you don’t have it, but you do have the arguments, you can use wp_next_scheduled() to retrieve its timestamp. So we can do something like this if we want to remove a single, specific event:

$hook = 'publish_future_post'; // The event hook that publishes scheduled posts
$args = [1234]; // Sequential array with post ID as the one and only item
$timestamp = wp_next_scheduled( $hook, $args ); // Get timestamp
if( is_int( $timestamp ) ) {
    // It was found! Now let's remove it
    $remove = wp_unschedule_event( $timestamp, $hook, $args, true ); // I want to see any errors
    if( is_wp_error( $remove ) {
        // Log the error
        error_log(
            $remove->get_error_message(),
            3,
            WP_CONTENT_DIR . '/debug.log'
        )
    }
}

Related Post Module Attributes Before

array(29) {
  ["post_type"]=>
  bool(false)
  ["post_id"]=>
  string(5) "23094"
  ["exclude"]=>
  string(2) "on"
  ["title"]=>
  string(27) "You might also like…"
  ["description"]=>
  string(0) ""
  ["max"]=>
  string(1) "4"
  ["post_ids"]=>
  string(0) ""
  ["exclude_ids"]=>
  string(0) ""
  ["is_series"]=>
  string(0) ""
  ["featured_term"]=>
  string(0) ""
  ["exclude_terms"]=>
  string(0) ""
  ["exclusive"]=>
  string(0) ""
  ["order"]=>
  string(4) "DESC"
  ["show_image"]=>
  string(2) "on"
  ["image_size"]=>
  string(6) "medium"
  ["menu_order_label"]=>
  string(0) ""
  ["show_order_label"]=>
  string(2) "on"
  ["show_date"]=>
  string(2) "on"
  ["show_meta_keys"]=>
  string(2) "on"
  ["show_modified"]=>
  string(0) ""
  ["show_author"]=>
  string(0) ""
  ["show_categories"]=>
  string(0) ""
  ["show_primary_category"]=>
  string(0) ""
  ["show_description"]=>
  string(0) ""
  ["show_reading_time"]=>
  string(2) "on"
  ["show_cta"]=>
  string(2) "on"
  ["cta"]=>
  string(9) "Read more"
  ["autoplay"]=>
  string(0) ""
  ["allow_sticky"]=>
  string(0) ""
}

Related Post Module Attributes

array(29) {
  ["post_type"]=>
  bool(false)
  ["post_id"]=>
  string(5) "23094"
  ["exclude"]=>
  string(2) "on"
  ["title"]=>
  string(27) "You might also like…"
  ["description"]=>
  string(0) ""
  ["max"]=>
  string(1) "4"
  ["post_ids"]=>
  string(0) ""
  ["exclude_ids"]=>
  string(0) ""
  ["is_series"]=>
  string(0) ""
  ["featured_term"]=>
  string(0) ""
  ["exclude_terms"]=>
  string(0) ""
  ["exclusive"]=>
  string(0) ""
  ["order"]=>
  string(4) "DESC"
  ["show_image"]=>
  string(2) "on"
  ["image_size"]=>
  string(6) "medium"
  ["menu_order_label"]=>
  string(0) ""
  ["show_order_label"]=>
  string(2) "on"
  ["show_date"]=>
  string(2) "on"
  ["show_meta_keys"]=>
  string(2) "on"
  ["show_modified"]=>
  string(0) ""
  ["show_author"]=>
  string(0) ""
  ["show_categories"]=>
  string(0) ""
  ["show_primary_category"]=>
  string(0) ""
  ["show_description"]=>
  string(0) ""
  ["show_reading_time"]=>
  string(2) "on"
  ["show_cta"]=>
  string(2) "on"
  ["cta"]=>
  string(9) "Read more"
  ["autoplay"]=>
  string(0) ""
  ["allow_sticky"]=>
  string(0) ""
}

Nobody has commented on this yet, be the first!

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