WordPress wp_schedule_single_event Example: Queue a One-Off Task Safely
Queue one-time WordPress follow-up tasks without duplicate scheduling, oversized arguments, or recurring cron misuse.
Published
April 25, 2026
Reading Time
2 min read
Updated
April 25, 2026

Implementation Notes
Extension points, code paths, and implementation choices that should survive contact with production.
Best For
WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.
Primary Topics
Editorial Focus
Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on April 25, 2026.
Full Report
Last reviewed: April 25, 2026
Not every background task in WordPress should recur forever. Sometimes a plugin needs a one-off follow-up after a user action: send a delayed digest, retry a failed sync, clean a temporary export, or recheck a resource later. That is where wp_schedule_single_event() fits better than a recurring cron schedule.
This guide shows how to queue a one-time event safely, avoid duplicate scheduling, and keep the callback arguments aligned so the event does not multiply by accident.
Schedule the follow-up after a real action
<?php
function vulnwp_queue_export_cleanup( $export_id ) {
$args = array( (int) $export_id );
$timestamp = time() + ( 30 * MINUTE_IN_SECONDS );
if ( wp_next_scheduled( 'vulnwp_cleanup_export', $args ) ) {
return;
}
wp_schedule_single_event( $timestamp, 'vulnwp_cleanup_export', $args );
}
The scheduling call belongs inside a real user or plugin action. If this code runs on every request, WordPress will fill the cron array with unnecessary work.
Register the callback
add_action( 'vulnwp_cleanup_export', 'vulnwp_cleanup_export_callback', 10, 1 );
function vulnwp_cleanup_export_callback( $export_id ) {
$export_id = (int) $export_id;
if ( $export_id <= 0 ) {
return;
}
delete_transient( 'vulnwp_export_' . $export_id );
}
The callback should still validate its inputs. Scheduled events are internal, but defensive code is cheaper than debugging corrupted state later.
Arguments must match on duplicate checks
WordPress uses the hook name and arguments together to identify scheduled events. If you check wp_next_scheduled() without the same arguments you used during scheduling, duplicate jobs can slip in.
$args = array( (int) $export_id );
if ( ! wp_next_scheduled( 'vulnwp_cleanup_export', $args ) ) {
wp_schedule_single_event( time() + HOUR_IN_SECONDS, 'vulnwp_cleanup_export', $args );
}
Production checklist
- Schedule one-off events only after a real trigger, not on every page load.
- Check for an existing event with the same arguments first.
- Keep arguments small and serializable.
- Validate arguments again in the callback.
- Remember that WordPress cron runs on traffic unless a real system cron triggers it.
- Use recurring cron only when the job truly repeats.
Common mistakes
- Scheduling from runtime code on every request. That creates event duplication fast.
- Checking
wp_next_scheduled()without matching args. WordPress then sees different jobs. - Passing huge payloads in arguments. Use IDs and fetch the real data later.
- Expecting second-level precision. WP-Cron is traffic-driven unless you trigger it externally.
- Using recurring events for one-off cleanup. That leaves unnecessary schedules behind.
Related reading
If the task should recur, use the recurring cron article instead. If the event fires after a form submission or admin flow, pair it with the admin_post handler guide.


