WP-Cron is WordPress’s built-in task scheduler, but it is not a continuously running clock. WordPress checks for due events when someone requests a page. If nobody visits after a task becomes due, the task waits for the next request, so scheduled posts, backups, email queues, updates, and other jobs can run late. For most ordinary sites, the default trigger is adequate. Sites with sparse traffic or strict timing requirements can use a host or operating-system scheduler to request wp-cron.php on a chosen cadence.
This guide explains the execution model, shows when an external scheduler is worthwhile, gives safe setup steps, and provides a troubleshooting path for missed events.
As an Amazon Associate I earn from qualifying purchases.
What WP-Cron is—and what it is not
WP-Cron is WordPress’s task-scheduling system. Core features such as scheduled post publishing and update checks use it, and plugins can register their own recurring or one-time work. WordPress stores events with a scheduled timestamp, a hook name, and the arguments needed by the callback that handles the work.
Free tools Windows power users keep installed
One-click scans. No signup required.
The important distinction is that WP-Cron is request-triggered. The WordPress handbook puts it plainly: “WP-Cron does not run constantly as the system cron does; it is only triggered on page load.” When a request arrives, WordPress checks the event queue. Events whose scheduled time has passed are eligible to run during that request. The scheduled timestamp therefore means “the work is due from this point,” not “the callback will begin at this exact second.” See the WordPress Cron Plugin Handbook for the core behavior.
#1 Best Overall
- WP-Cron: included with WordPress and activated by site requests.
- System cron or a host scheduler: an operating-system or hosting service that runs independently on a timetable and can request WordPress’s cron endpoint.
Using WP-Cron does not require a continuously running WordPress process. It does require the site to receive a request after an event is due, unless you add an outside trigger.
How a scheduled task moves from due time to execution
1. A plugin or WordPress core registers an event
A feature schedules an event with a hook. Recurring work generally uses wp_schedule_event(); a one-off task uses wp_schedule_single_event(). The event includes a first-run timestamp and, for recurring work, an interval. WordPress’s built-in recurrence names are hourly, twicedaily, daily, and weekly. Developers can add other intervals through the cron_schedules filter. The scheduling reference is documented in Scheduling WP-Cron Events and Understanding WP-Cron Scheduling.
2. The event reaches its scheduled timestamp
At this point the event is due, but no PHP callback has necessarily run. A low-traffic site may leave the event waiting for minutes or hours.
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 →3. A request starts the cron check
On a normal page request, WordPress checks whether cron work is waiting. Depending on the request and server configuration, WordPress starts a loopback HTTP request to the site’s wp-cron.php endpoint. That process looks for due events and dispatches their hooks.
4. The hook invokes its callback
The callback attached to the hook performs the actual work: publishing a post, sending a queued message, removing expired data, or calling an external service. If the callback fails, is not registered, or cannot complete within the server’s limits, the event can remain incomplete even though WP-Cron itself was triggered.
Why scheduled posts and plugin jobs run late
Late execution usually has a specific cause. Start with the timing model before changing configuration.
- No requests after the due time: a staging site, private site, or low-traffic site may not trigger the next check promptly.
- Loopback requests are blocked: WordPress may be unable to request its own URL because of a firewall, security rule, DNS problem, SSL issue, or HTTP authentication.
- The event was never registered: activation code may not have run, the hook name may differ from the callback, or a plugin may have been disabled.
- The callback is missing or failing: an event can exist in the queue while its hook has no usable callback, or the callback can hit a PHP error, timeout, remote API failure, or permission problem.
- Duplicate or stale schedules: code that schedules a recurring event on every request can create overlapping entries; removed features can leave orphaned events behind.
- External scheduler misconfiguration: an outside trigger may be disabled, point to another WordPress installation, use the wrong protocol, or be blocked by the host.
WP-Cron does not promise exact wall-clock execution. If a post must become public within a narrow window, measure the delay you are seeing and consider an external trigger rather than assuming the default mechanism is broken.
Recommended Free Tools
Default WP-Cron versus an external scheduler
| Consideration | Default page-load trigger | External system or host scheduler |
|---|---|---|
| When work is triggered | After an event is due and a site request starts the check; timing depends on traffic. | A host or operating-system scheduler makes a request on its configured cadence. |
| Setup | Built into WordPress; normally no server access is needed. | Requires access to a hosting scheduler, operating-system task scheduler, or another supported request mechanism. |
| Timing control | Due work may wait during quiet periods. | More predictable checks, limited by the chosen cadence and server execution time. |
| Ongoing responsibility | WordPress handles the trigger; you still need healthy callbacks and loopbacks. | You must keep the scheduler enabled, target the correct installation, and maintain permissions, networking, and command settings. |
| WordPress’s position | The normal option for many sites. | Optional replacement when timing or operational requirements justify it. |
WordPress’s PHP optimization guidance says cron checks add some time and load, but the system is designed to use minimal resources. Replacing it is not a mandatory performance upgrade. Read PHP Optimization before changing a working installation.
When an external trigger is worth using
Consider an external scheduler when one or more of these conditions apply:
- The site receives very few visits, yet scheduled work must run without waiting for the next visitor.
- A business process depends on regular processing, such as a queue, data import, expiry job, or time-sensitive publication.
- You need an operational schedule you can monitor independently of web traffic.
- You have confirmed that events are registered correctly and loopback requests work, but page-load triggering still produces unacceptable delays.
Keep the built-in trigger when the site has regular traffic, jobs are tolerant of delay, and there is no operational need for server-level scheduling. An external scheduler adds another component to configure and maintain; it should solve an observed requirement, not be installed automatically on every site.
How to configure a host or system scheduler
The exact interface, command, account, permissions, and cadence depend on your host and operating system. WordPress’s official guide covers both Windows Task Scheduler and Linux/macOS cron patterns in Hooking WP-Cron Into the System Task Scheduler. Treat the following as a decision and verification sequence rather than a universal command.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, 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 minuteStep 1: Confirm the site URL and installation
Identify the exact HTTPS URL for the WordPress installation and the corresponding wp-cron.php endpoint. A site installed in a subdirectory has a different endpoint from a site installed at the domain root. Confirm the target with your hosting provider if redirects, staging environments, or multiple installations are present.
Step 2: Choose a cadence
Pick an interval based on the work’s tolerance for delay. The official setup documentation shows examples including an every-15-minutes pattern and a daily pattern. A shorter interval causes more frequent checks; it does not make a callback complete faster, and it cannot compensate for a failing callback. Use the least frequent schedule that meets the requirement.
Step 3: Add the scheduler action
In a Linux or macOS environment, create a cron entry that makes an HTTP request to the confirmed wp-cron.php URL. In Windows Task Scheduler, create a task with the desired trigger and an action that requests the same endpoint. Some hosts provide a control-panel form instead of shell access. Follow the provider’s required request tool, user account, timeout, and output-handling rules.
Step 4: Prevent two independent triggers
After verifying that the external request reaches the correct installation, add this line to wp-config.php, above the line that says WordPress is done editing:
define( 'DISABLE_WP_CRON', true );
This stops the normal page-load trigger from continuing to spawn checks in parallel with the external scheduler. Do not add the constant until the outside trigger is active; otherwise, a mistake in the scheduler can leave the site with no cron trigger at all.
Step 5: Verify from both sides
- Run the scheduler manually once, if your host allows it.
- Check the scheduler’s execution log for a successful action and the expected target URL.
- Confirm in WordPress that a known due event is processed.
- Leave the scheduler running for several intervals and watch for missed executions, HTTP errors, redirects, or authentication failures.
If your provider restricts outbound requests, local PHP execution, or scheduled tasks, ask support which request method and interval are permitted. Host limits vary; there is no single command that is valid for every server.
How to test WP-Cron with WP-CLI
When WP-CLI is available and run from the correct WordPress installation, use:
Rank #4
wp cron test
The command checks whether DISABLE_WP_CRON is set, warns about ALTERNATE_WP_CRON, and attempts to spawn cron over HTTP. A non-200 response is a signal to investigate, not a complete diagnosis. A successful test proves that this basic spawning check worked; it does not prove that every plugin event is registered, that every callback succeeds, or that a future external scheduler will remain healthy. See the current wp cron test documentation for the command’s checks and output.
A systematic checklist for missed events
Check the event itself
- Determine whether the feature actually registered an event.
- Confirm the hook name used for scheduling matches the hook connected to the callback.
- Check that the event has a future or due timestamp and the expected recurrence.
- Look for duplicate entries created by code that schedules on every request.
- Remove schedules belonging to a deactivated or removed feature so WordPress does not keep attempting orphaned work.
For custom plugin code, use wp_next_scheduled() before adding a recurring event. This prevents repeated requests from creating duplicate schedules. Unschedule events when a plugin or feature is deactivated. WordPress’s scheduling guidance explains these patterns in Scheduling WP-Cron Events.
Check the callback
- Verify that the callback is attached with the expected action hook and accepted arguments.
- Review PHP error logs for fatal errors, timeouts, memory exhaustion, and permission failures.
- Check dependencies such as remote APIs, mail services, files, database tables, and authentication tokens.
- Test the operation manually where the plugin provides a safe manual-run option.
Check loopback requests
WordPress uses loopbacks—requests from the site back to itself—for several background operations. If Site Health reports a loopback problem, first test for plugin conflicts, then theme conflicts. If the problem remains, ask the host whether firewall rules, security software, DNS resolution, SSL validation, or HTTP authentication prevents the site from requesting its own URL. Follow the troubleshooting sequence in Loopbacks.
Check an external scheduler
- Confirm the task is enabled and has run recently.
- Verify its URL or local command points to the intended production or staging installation.
- Check the scheduler account’s permissions and the host’s allowed request method.
- Inspect HTTP status codes, redirects, TLS errors, and timeout messages.
- Make sure
DISABLE_WP_CRONwas not enabled before the outside trigger was working.
Developer practices that prevent cron problems
Use a unique hook and a deliberate schedule
Choose a hook name specific to the feature, attach the callback during plugin initialization, and select a recurrence that matches the work. A five-minute task does not become reliable merely because it is scheduled every five minutes; the callback must also finish within available resources and tolerate retries.
Guard recurring registration
Code that runs on many requests must not blindly call wp_schedule_event() each time. Check wp_next_scheduled() first, then register only when no matching event exists. This avoids duplicate processing and unnecessary load.
Clean up on deactivation
When a plugin or feature is no longer active, unschedule its events. Leaving a hook behind can create repeated attempts to run code that no longer exists, producing log noise and wasted work.
Best Value
Design callbacks for real-world execution
- Process bounded batches instead of attempting an unbounded data set in one request.
- Record useful errors and completion state so a failed run can be diagnosed.
- Make operations idempotent where possible, so a retry does not duplicate a publication, payment, message, or record.
- Handle remote-service timeouts and temporary failures without marking unfinished work as complete.
- Keep credentials and permissions available to the account that actually runs the callback.
Common configuration mistakes
Disabling WP-Cron without replacing its trigger
Setting DISABLE_WP_CRON to true only suppresses the page-load check. It does not create a scheduler. Always establish and test the host or system task first.
Expecting a recurrence label to be an exact timer
“Hourly” describes the event interval, not a guarantee that a callback starts on the minute. The trigger, queue, server load, and callback duration still affect completion time.
Changing cron before checking the event
An external scheduler cannot fix a missing hook, an unregistered event, a fatal callback, or a blocked remote dependency. Test registration and execution in that order.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Assuming a passing spawn test proves every job works
wp cron test validates basic spawning behavior. It does not inspect every plugin’s schedule or callback, so continue with event and loopback checks when a specific task is late.
A practical decision path
- Is the task allowed to wait for the next visitor? If yes, retain the default trigger and monitor the task.
- Is traffic sparse or timing operationally important? If yes, plan an external scheduler.
- Before changing anything, is the event registered and its callback healthy? If no, fix the feature or plugin first.
- Do loopback requests work? If no, resolve the plugin, theme, security, DNS, SSL, or authentication issue with the host as needed.
- Can your host run a reliable scheduled request? If yes, configure it, verify several runs, and then disable the page-load trigger.
- Can you monitor the new component? If no, keep the simpler default until you have a way to detect failed scheduler runs.
The right setup is the one that meets the task’s timing requirement while keeping the fewest moving parts. WP-Cron is a simple task scheduler, not a real-time job queue; understanding that boundary prevents both needless server changes and unexplained late work.
Quick Recap
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.

