arrow_back
WordPress

WordPress Cron: wp_schedule_event, WP-Cron, and system cron

Andrew Dorokhov Andrew Dorokhov schedule 3 min read

In WordPress, we can use the built-in WP-Cron system to schedule and execute tasks at specific intervals. WP-Cron allows us to schedule tasks without relying on the server’s cron scheduler directly. Instead, WordPress handles the scheduling internally.

The mechanism is simple: on every page load WordPress checks the list of scheduled tasks to see what needs to be run. This is also its main weakness — on a site with no traffic nothing gets executed, which is why a real system cron job is the more reliable setup.

Configuration

Prevent WP-Cron from running on every request by adding the following to wp-config.php:

define('DISABLE_WP_CRON', true);

Instead of this we can set up a system-level cron job to execute wp-cron.php periodically. For example:

*/5 * * * * php /path-to-your-site/wp-cron.php

WordPress Cron Event Hooks and Descriptions

Event Hook Description
wp_version_check Checks for WordPress core updates twice a day.
wp_update_plugins Checks for plugin updates twice a day.
wp_update_themes Checks for theme updates twice a day.
wp_scheduled_delete Deletes trash for posts and comments once a day.
delete_expired_transients Clears expired transients once a day.
wp_scheduled_auto_draft_delete Deletes auto-draft posts once a day.
wp_privacy_delete_old_export_files Deletes old export files once a day.
wp_site_health_scheduled_check Checks and updates the site health status once a week.
wp_https_detection Checks if HTTPS is supported on the site twice a day.

Adding the Hook

add_action('my_hourly_task', 'my_hourly_function');

Schedule a Recurring Event

wp_schedule_event( $timestamp, $recurrence, $hook );

// $timestamp  - the starting point from which the hook begins to work.
// $recurrence - how often the action should repeat: hourly, twicedaily, daily
//               (plus weekly since WP 5.4, and any custom interval you register).
// $hook       - the name of the hook.

wp_next_scheduled() takes the name of the hook and returns either the timestamp of the next execution or false, meaning the task is not scheduled. Checking it first prevents the same event from being queued twice:

if ( ! wp_next_scheduled( 'my_hourly_task' ) ) {
    wp_schedule_event( time(), 'hourly', 'my_hourly_task' );
}

Schedule a one time event

if ( ! wp_next_scheduled( 'custom_one_time_cron' ) ) {
    wp_schedule_single_event( $timestamp, 'custom_one_time_cron' );
}

Unscheduling tasks

register_deactivation_hook( __FILE__, 'bl_deactivate' ); 

function bl_deactivate() {
    $timestamp = wp_next_scheduled( 'bl_cron_hook' );
    wp_unschedule_event( $timestamp, 'bl_cron_hook' );
}

More easy way:

// Unschedules all events attached to the hook with the specified arguments.
wp_clear_scheduled_hook( 'bl_cron_hook' );

Add Custom Cron Interval

WordPress doesn’t have a built-in interval for monthly execution, so you need to add a custom interval for a month. You can do this using the cron_schedules filter. Add this code to your theme’s functions.php file or a custom plugin:

add_filter('cron_schedules', 'custom_monthly_cron_schedule');
function custom_monthly_cron_schedule($schedules) {
    $schedules['monthly'] = array(
        'interval' => 30 * 24 * 60 * 60, // 30 days in seconds
        'display' => __('Once Monthly')
    );
    return $schedules;
}

Diagnostics of issues

Tools -> Site health.

site-health.png

code

Need Help with Development?

Happy to help — reach out via the contacts or go straight to my Upwork profile.

work View Upwork Profile arrow_forward
folder_off

No articles yet in this section.