WP-Cron Event Generator
Generate a scheduled WP-Cron event: the schedule, the callback, scheduling on activation and the cleanup that stops it running after deactivation.
<?php
/**
* The "my_plugin_daily_cleanup" scheduled event.
*/
/**
* Puts the event in the schedule if it is not there already.
*/
function my_plugin_run_daily_cleanup_activate() {
$args = array();
if ( wp_next_scheduled( 'my_plugin_daily_cleanup', $args ) ) {
return;
}
$first = time();
wp_schedule_event( $first, 'daily', 'my_plugin_daily_cleanup', $args );
}
register_activation_hook( __FILE__, 'my_plugin_run_daily_cleanup_activate' );
/**
* Removes the event so it stops firing once the plugin is gone.
*/
function my_plugin_run_daily_cleanup_deactivate() {
$args = array();
$timestamp = wp_next_scheduled( 'my_plugin_daily_cleanup', $args );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, 'my_plugin_daily_cleanup', $args );
}
}
register_deactivation_hook( __FILE__, 'my_plugin_run_daily_cleanup_deactivate' );
/**
* Runs when the event fires.
*/
function my_plugin_run_daily_cleanup() {
// WP-Cron can start a second run before a slow one finishes.
$lock = 'my_plugin_daily_cleanup_lock';
if ( get_transient( $lock ) ) {
return;
}
set_transient( $lock, 1, 10 * MINUTE_IN_SECONDS );
// Your work here.
delete_transient( $lock );
}
add_action( 'my_plugin_daily_cleanup', 'my_plugin_run_daily_cleanup' );
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Pick how often the job runs and the generator writes the whole event: the schedule, the code that books it, the callback, and the cleanup that stops it firing after the plugin is gone.
How to use
- Name the event hook. WP-Cron stores that string, so prefix it: two plugins sharing a hook run each other’s callbacks.
- Choose the recurrence. Hourly, twice daily, daily and weekly come with WordPress; custom registers your own interval through the
cron_schedulesfilter. - Decide where scheduling happens. Activation books it once; init re-checks on every request, which recovers the event if it is ever lost.
- Keep the deactivation cleanup on. Without it the event stays booked, firing a hook nothing answers.
- Leave the overlap guard on for anything slow. WP-Cron will happily start a second run while the first is still going.
Example
A fifteen-minute sync with two arguments, booked from init so a lost event comes back, first run pushed an hour out:
function acme_run_inventory_sync_activate() {
$args = array(
'batch',
'full',
);
if ( wp_next_scheduled( 'acme_sync_inventory', $args ) ) {
return;
}
$first = time() + HOUR_IN_SECONDS;
wp_schedule_event( $first, 'every_fifteen_minutes', 'acme_sync_inventory', $args );
}
add_action( 'init', 'acme_run_inventory_sync_activate' );
Arguments are part of the event’s identity. Unscheduling needs the same values in the same order, which is why the generated cleanup rebuilds that array rather than passing an empty one.
Pitfalls
- WP-Cron is not cron. Nothing runs until someone visits the site, so a daily job on a quiet site can be days late.
- Scheduling without
wp_next_scheduled()books a duplicate on every run. Oninitthat means a new event on every page load. - Deactivation cleanup is not automatic. An uncleared event stays in the schedule after the plugin is gone, firing a hook with no listener.
- The arguments array is part of the event identity. Unscheduling with different arguments finds nothing and silently leaves the event booked.
- A custom interval under 60 seconds is wasted: WP-Cron is triggered by traffic and coalesces anything due.
- Two overlapping runs are normal on a busy site. Without the transient lock a slow job can run against itself.
- A fatal in the callback stops every later event in that run, not just yours.
wp_schedule_single_event()fires once and is then gone, so it never needs unscheduling, but it also never retries if it fails.
Compatibility
wp_schedule_event(), wp_next_scheduled() and wp_unschedule_event() have been stable since WordPress 2.1. The weekly schedule needs WordPress 5.4 or later; on older versions register it yourself with a custom interval. The generated code targets PHP 7.0 and up, and the tool runs entirely in your browser.
Frequently asked questions
Why has my event not run?
wp-cron.php and set DISABLE_WP_CRON to true.How do I check what is scheduled?
wp cron event list with WP-CLI shows every event and its next run. It is the fastest way to catch a duplicate.