WordPress Cron Schedules: How to Set Recurring Events

WordPress Cron Schedules: How to Set Recurring Events

WordPress cron schedules let you run code on a repeating timer, from clearing a cache every hour to emailing a digest once a week. Unlike a real server cron, WP-Cron is built into WordPress itself, so the recurrence intervals come from PHP, not a crontab line. Here is how the schedules work and how to register your own.

The built-in WordPress cron schedules

Out of the box, WordPress ships with four recurrence schedules you can attach an event to:

  • hourly: every 3600 seconds.
  • twicedaily: every 12 hours.
  • daily: once every 24 hours.
  • weekly: once every 7 days.

These names are what you pass when you schedule an event. If none of them fit, you add your own.

Adding a custom interval

To create a schedule that is not in the default list, hook into the cron_schedules filter and return your interval in seconds plus a display name:

add_filter( 'cron_schedules', function( $schedules ) {
    $schedules['every_five_minutes'] = array(
        'interval' => 300,
        'display'  => 'Every Five Minutes',
    );
    return $schedules;
} );

The WordPress Cron Schedules tool generates this snippet for any interval you type, so you do not have to do the seconds math by hand.

Scheduling an event with wp_schedule_event

A schedule on its own does nothing. You register a recurring event with wp_schedule_event, pointing it at a custom action hook, then attach your function to that hook:

  1. Open the WordPress Cron Schedules tool and pick or build your interval.
  2. Register the event once, guarding it so it is not added twice:
if ( ! wp_next_scheduled( 'my_cleanup_event' ) ) {
    wp_schedule_event( time(), 'hourly', 'my_cleanup_event' );
}
  1. Hook your callback to the same action name:
add_action( 'my_cleanup_event', 'my_cleanup_function' );
  1. On plugin deactivation, clear it with wp_clear_scheduled_hook( 'my_cleanup_event' ) so it does not linger.

WP-Cron is not real cron

This is the part that trips people up. WP-Cron is traffic-triggered: tasks only fire when someone visits the site and WordPress checks whether anything is due. A low-traffic site can miss scheduled events, and a high-traffic site can fire the check on nearly every request. It also does not use system cron expressions like */5 * * * *; those five-field strings belong to a server crontab, not to WordPress.

For reliability, disable the built-in trigger with define( 'DISABLE_WP_CRON', true ); in wp-config.php, then add a real server cron that calls wp-cron.php on a fixed schedule. That gives you accurate timing while still using the same wp_schedule_event hooks.

Pick an interval, register it with wp_schedule_event, and back it with a real server cron if timing matters.

← All posts