What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
WordPress cron, usually called WP-Cron, runs scheduled plugin and core tasks such as publishing posts, sending queued mail and cleaning data. It is triggered during site requests rather than by a continuously running daemon, so low-traffic sites can run tasks late. You can create and maintain events with WordPress PHP APIs, inspect or execute them with WP-CLI, and hand timing to the server’s scheduler when a predictable run time matters.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
This guide shows how to register a recurring event safely, schedule one-off work, prevent duplicate events, migrate execution to Linux, macOS or Windows scheduling, remove obsolete jobs and diagnose missed or repeated runs.
As an Amazon Associate I earn from qualifying purchases.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsWhat WP-Cron is and why timing can drift
WP-Cron is WordPress’s hook-based scheduling system. A plugin registers a uniquely named hook and connects it to a callback. It then places an event for that hook in WordPress’s scheduled-event queue. When a request reaches the site, WordPress checks whether work is due and attempts to spawn a cron request that executes the callbacks.
There is no permanent WP-Cron worker checking the clock every second. A site with few visitors may not receive a request near the intended time, while a busy site can generate many opportunities to check the queue. The WordPress Developer Resources Plugin Handbook therefore cautions that WP-Cron does not run continuously and can be unsuitable for critical tasks that must run on time.
#1 Best Overall
WP-Cron is appropriate for ordinary asynchronous work where a delay of a few minutes is acceptable. If an invoice, import, backup or other operation must start on a predictable schedule, use the operating system’s scheduler to invoke WordPress and disable request-triggered spawning.
How a scheduled event moves from code to execution
- Registration: the plugin calls
add_action()with its unique hook and callback. - Scheduling: activation code calls
wp_schedule_event()for recurring work orwp_schedule_single_event()for a one-time run. - Due check: a normal page request causes WordPress to look for due events and attempt a cron request.
- Callback: WordPress invokes the function attached to the hook. A recurring event is rescheduled according to its interval.
- Lifecycle management: deactivation code removes events that the plugin no longer needs.
The first-run timestamp is separate from the recurrence name. Choosing hourly, for example, does not mean the callback runs at the top of every clock hour; it means WordPress calculates later runs from the event’s schedule after the first timestamp.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallChoose the execution model
| Characteristic | Visitor-triggered WP-Cron | Server-triggered scheduling |
|---|---|---|
| Execution trigger | WordPress requests caused by page loads, feeds, API calls or other traffic | Linux/macOS cron, Windows Task Scheduler or another host scheduler requests WordPress at a configured interval |
| Timing predictability | Variable on low-traffic or overloaded sites | More predictable, subject to the host scheduler and task duration |
| Server access | Works with ordinary WordPress access | Requires shell, hosting-panel or Task Scheduler access |
| Duplicate-event risk | High if scheduling code runs on every request instead of a controlled activation path | The scheduler starts execution, but duplicate WordPress events still have to be prevented in plugin code |
| Visibility | WP-CLI can show the queue and next-run times | WP-CLI plus the server scheduler show both the WordPress queue and the external trigger |
| Cleanup | Use WordPress unscheduling APIs and a deactivation hook | Remove the WordPress event and, if applicable, the operating-system schedule |
Keep visitor-triggered execution when approximate timing is acceptable and you do not control the server. Move to an operating-system scheduler when lateness has a business or operational cost.
Prerequisites and design rules
- Use a hook name with a project-specific prefix, such as
bl_cron_hook, to avoid collisions with another plugin. - Put event registration in plugin activation or another explicitly controlled setup path, not in code that executes on every page load.
- Check
wp_next_scheduled()before adding a recurring event. - Make callbacks idempotent: a retry should not create duplicate records, send the same message twice or corrupt state.
- Keep callbacks defensive. Check input, handle remote or database failures and record enough information to diagnose a failed run.
- Plan deactivation cleanup before shipping the feature. Deactivating a plugin does not automatically erase its scheduled events.
Build a recurring WP-Cron event in a plugin
1. Attach a uniquely prefixed hook
Place the action registration in the plugin’s main file or another file that is loaded on every request:
add_action( 'bl_cron_hook', 'bl_cron_exec' );
function bl_cron_exec() {
update_option( 'bl_cron_last_run', current_time( 'mysql', true ) );
// Perform a small, repeatable unit of work here.
}
The callback above records a UTC timestamp as a simple health marker. Replace the comment with the task your plugin owns. Do not put a long, unbounded batch in one callback; process a bounded page of work and leave the next page for a later run.
Rank #2
2. Schedule once during activation
Use the activation hook to create the event and guard it with wp_next_scheduled():
register_activation_hook( __FILE__, 'bl_cron_activate' );
function bl_cron_activate() {
if ( ! wp_next_scheduled( 'bl_cron_hook' ) ) {
wp_schedule_event( time() + 300, 'hourly', 'bl_cron_hook' );
}
}
time() + 300 gives the site five minutes before the first attempt. The second argument, hourly, is a registered recurrence name; the final argument is the hook that identifies the callback. The guard means reactivation or another initialization path does not create a second copy of the same event.
Use a recurrence that matches the work. A frequent schedule is not a substitute for an efficient callback: if a run can take longer than the interval, design the callback to claim and finish discrete items so overlapping work cannot repeat side effects.
3. Use a one-time event when recurrence is wrong
For a delayed, one-off operation, use the single-event API instead of creating a recurring schedule:
wp_schedule_single_event( time() + 3600, 'bl_cron_hook' );
This places one execution approximately one hour in the future, subject to the trigger model. If the callback needs arguments, pass them as the API’s additional argument array and define the callback to accept the same values. Before scheduling a one-off event that could be requested repeatedly, apply your own unique order, post or job identifier so a user refresh cannot enqueue the same work many times.
Free tools Windows power users keep installed
One-click scans. No signup required.
Inspect and control events with WP-CLI
Run these commands from the WordPress installation directory as the site’s appropriate system user. WP-CLI’s cron commands provide operational visibility without opening the database directly.
Test the spawning mechanism
wp cron test
This checks whether WordPress can start its cron-spawning mechanism. A failure points to a loopback request, HTTP authentication, DNS, firewall, SSL or server-configuration problem rather than to one particular plugin callback.
List hooks, next runs and recurrence
wp cron event list --fields=hook,next_run_gmt,recurrence --format=table
The table shows each scheduled hook, its next run in GMT and recurrence data. Use it to spot an unexpectedly large queue, a hook with no recurrence when you expected one, or several rows for the same hook that indicate duplicate scheduling.
Run all currently due events
wp cron event run --due-now
This executes events whose scheduled time has arrived. It is useful after correcting a blocked loopback request or when you need to drain due work during maintenance. Run it with care on a production site: every due callback will execute, and a callback that is not idempotent can repeat its side effects.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Schedule a test event
wp cron event schedule cron_test now hourly
The command creates a recurring cron_test event starting now. WP-CLI also accepts a Unix timestamp or textual date-time and optional callback arguments. Use a uniquely named test hook in a staging environment when possible, then verify it with the list command and remove it after testing.
Rank #4
Delete or unschedule an event
wp cron event delete cron_test
wp cron event unschedule cron_test
delete removes all events for the specified hook. unschedule removes scheduled events for that hook where supported by the installed WP-CLI version. Confirm the command’s result with wp cron event list; do not remove a shared hook until you know which plugin owns it.
Move execution to the server scheduler
Use an operating-system scheduler when visitor traffic is too irregular for the required timing. The WordPress handbook recommends requesting wp-cron.php from Linux or macOS cron, or from Windows Task Scheduler, at the interval you choose.
1. Disable request-triggered spawning
Add this line to wp-config.php before the file’s stop-editing comment:
Recommended Free Tools
define( 'DISABLE_WP_CRON', true );
Without this setting, page loads continue trying to spawn WP-Cron even after you configure the server scheduler. That creates needless work and can make it difficult to tell which trigger is responsible for a run.
2. Configure Linux or macOS cron
Open the crontab for the account that can run WordPress commands:
Best Value
crontab -e
A practical WP-CLI schedule is:
*/5 * * * * cd /var/www/html && wp cron event run --due-now
This asks WP-CLI to execute due events every five minutes. Replace /var/www/html with the actual document root and use the correct PHP/WP-CLI environment for the site. Alternatively, configure the scheduler to make an HTTP request to the site’s wp-cron.php endpoint. Protect that endpoint and account for authentication, redirects, SSL and firewall rules when testing.
3. Configure Windows Task Scheduler
- Create a basic task with a trigger at the interval your workload requires.
- Set the action to run the PHP executable with the site’s WP-CLI command, or to request the site’s
wp-cron.phpendpoint. - Run the task whether or not the account is logged in if your hosting policy permits it.
- Review the task’s history and the WordPress event list after the first run.
Do not configure both an external scheduler and visitor-triggered spawning unintentionally. After the first scheduled run, use wp cron event list and application logs to verify that events advance once per interval.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Prevent duplicate cron events
The most common cause is scheduling code that runs during normal initialization:
// Risky: this can run on every request.
wp_schedule_event( time(), 'hourly', 'bl_cron_hook' );
Each request can add another row before the previous event is due. The safe pattern is a controlled activation path plus a guard:
if ( ! wp_next_scheduled( 'bl_cron_hook' ) ) {
wp_schedule_event( time() + 300, 'hourly', 'bl_cron_hook' );
}
If a migration or settings-save routine must repair a missing event, keep the same check and make the repair operation deliberate. When diagnosing duplicates, list the hook with WP-CLI, note how many rows exist and identify which deployment or activation path created them. Remove surplus rows only after confirming that the callback does not belong to another component.
Unschedule obsolete work during deactivation
WordPress can continue attempting a task after its plugin is deactivated or removed. The Plugin Handbook says it is important to unschedule tasks when they are no longer needed. Add a deactivation hook that retrieves the next timestamp and removes that event:
register_deactivation_hook( __FILE__, 'bl_cron_deactivate' );
function bl_cron_deactivate() {
$timestamp = wp_next_scheduled( 'bl_cron_hook' );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, 'bl_cron_hook' );
}
}
This pattern targets the next occurrence for the hook. If your plugin can create multiple occurrences or one-off events with different arguments, enumerate and remove each event your version supports, then verify the queue with WP-CLI. Deactivation should stop future work without deleting business data unless that behavior is explicitly part of the plugin’s documented uninstall process.
Quick Recap
Troubleshoot late, missing or repeated jobs
The scheduled post or task is late
- Check whether the site has enough requests to trigger WP-Cron near the intended time.
- Run
wp cron event list --fields=hook,next_run_gmt,recurrence --format=tableand compare the expected hook with its next-run time. - Use
wp cron testto test spawning. Investigate loopback HTTP failures, blocked DNS, SSL errors, basic authentication and firewall rules. - If exact timing matters, configure the server scheduler and set
DISABLE_WP_CRONinstead of relying on visitors.
The same task runs more than once
- Look for multiple rows of the hook in the event list.
- Search plugin code for scheduling calls that execute during ordinary requests.
- Add the
wp_next_scheduled()guard and move registration to activation or a controlled repair routine. - Make the callback idempotent so a retry cannot duplicate its external effect.
A task never appears in the queue
- Confirm the activation hook ran for the main plugin file that contains it.
- Check that the hook name in
add_action()exactly matches the name passed towp_schedule_event(). - Verify that the recurrence name is registered and that the scheduling call did not return a failure.
- Use WP-CLI to schedule a temporary test event and determine whether the problem is queue creation or callback code.
Due events accumulate
- Run due events manually with
wp cron event run --due-nowwhile monitoring resource use. - Inspect the callback for unbounded loops, slow remote requests or database operations that fail without advancing state.
- Break large work into bounded batches and store progress so a later run can continue safely.
- Check whether the external scheduler is disabled, misconfigured or running under an account without the required PHP or WordPress environment.
Operational practices for reliable callbacks
- Use explicit ownership: prefix hooks and document which plugin creates each one.
- Record outcomes: store a last-run timestamp or structured log entry, including failures and the item being retried.
- Protect against overlap: claim a batch before processing it, use a lock with an expiry, or otherwise ensure two workers cannot perform the same irreversible action simultaneously.
- Respect limits: design around PHP execution time, memory limits, remote API rate limits and database lock duration rather than assuming one callback can process an entire backlog.
- Separate scheduling from work: the scheduler should decide when to start; the callback should determine what remains and what can be safely retried.
- Test the complete lifecycle: activate, inspect, run a due event, deactivate, and confirm the hook is gone.
Quick management checklist
- Create a unique hook and attach a callback with
add_action(). - Schedule recurring work with
wp_schedule_event()only from activation or another controlled path. - Guard registration with
wp_next_scheduled(). - Use
wp_schedule_single_event()for one-off jobs. - Inspect the queue with
wp cron event listand test spawning withwp cron test. - Run due work with
wp cron event run --due-nowwhen diagnosing or draining a queue. - If timing must be predictable, schedule WP-Cron from the server and define
DISABLE_WP_CRONinwp-config.php. - Unschedule events in the plugin deactivation hook and verify cleanup.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




