Contents
Introduction — What is WP-Cron?
WP-Cron is WordPresss internal scheduling system for running time-based tasks (scheduled events). Unlike system cron daemons on servers, WP-Cron is triggered on page load: when someone requests a page and a scheduled event is due, WordPress will try to spawn the WP-Cron process via an HTTP request to wp-cron.php. WP-Cron is convenient because it works on many hosting environments without access to server cron, but it is not a real-time, always-reliable scheduler. Understanding its mechanics, common pitfalls, and how to schedule recurring events in PHP is essential for plugin and theme developers.
Core Concepts
- Hooks (actions): Scheduled events fire action hooks. You attach a callback using add_action(your_hook, your_callback).
- Schedule vs Single Event: Use wp_schedule_event() for recurring events and wp_schedule_single_event() for one-off executions.
- Intervals: WordPress provides built-in intervals (hourly, twicedaily, daily). You can add custom intervals with the cron_schedules filter.
- Timestamp: When scheduling you provide a Unix timestamp (seconds since epoch) indicating the first run time.
- Persistence: Scheduled events are stored in the WordPress options table (or object cache if persistent). If you use object caching that is not persistent, scheduled events may be lost.
Important Functions — Quick Reference
Function | Purpose |
wp_schedule_event() | Schedule a recurring event |
wp_schedule_single_event() | Schedule a one-time event |
wp_next_scheduled() | Get the next timestamp for a hook (optionally with args) |
wp_get_schedule() | Get the recurrence string for a hook |
wp_unschedule_event() | Remove a specific scheduled event (by timestamp hook) |
wp_clear_scheduled_hook() | Clear all scheduled events for a hook (optionally with args) |
wp_cron() | Run cron – used internally can be invoked via HTTP to wp-cron.php |
wp_reschedule_event() | Change timestamp for a scheduled event |
How WP-Cron Works (Internals)
- WordPress stores scheduled jobs in the options table as an associative array in the cron option (or in persistent object cache).
- On each front-end or admin request WordPress checks if any cron events are due (next scheduled timestamp <= current time) and, if so, triggers a background request calling wp-cron.php.
- wp-cron.php loads WordPress, evaluates and executes due events by firing the corresponding action hooks.
- If DISABLE_WP_CRON is defined as true in wp-config.php, WordPress will not spawn the wp-cron.php HTTP request on page loads (useful when you set up a real server cron to call wp-cron.php).
Scheduling a Recurring Event — Basic Example
Typical plugin pattern: schedule an event on plugin activation and clear it on deactivation. The example below schedules a custom hook to run hourly.
Notes on the example
- Always check wp_next_scheduled() to avoid scheduling duplicates.
- Use register_activation_hook() to schedule initial events and register_deactivation_hook() to remove them.
- Keep the callback function short heavy work should be delegated to background workers or queued processes.
Scheduling a One-Time Event
Use wp_schedule_single_event() for actions that must run once at a specific timestamp.
Adding Custom Intervals
To run jobs more frequently than hourly (for example every 5 minutes), add a custom schedule using the cron_schedules filter. Note that shared hosts and some caching/object cache configurations may not reliably execute very frequent cron jobs for high frequency consider a real server cron or background job queue.
5 MINUTE_IN_SECONDS, display => __( Every Five Minutes ), ) return schedules } // Schedule using the new interval if ( ! wp_next_scheduled( myplugin_five_min_event ) ) { wp_schedule_event( time(), every_five_minutes, myplugin_five_min_event ) } add_action( myplugin_five_min_event, myplugin_do_frequent_task ) function myplugin_do_frequent_task() { // frequent task code } ?>
Caveats with custom short intervals
- Running tasks every few minutes can be heavy on resources. Use sparingly.
- Some cache setups or object cache backends may not persist cron data if the cron schedule disappears after cache flush, use a persistent object cache or server cron.
Working with Arguments
Both wp_schedule_event() and wp_schedule_single_event() accept an optional array of arguments that will be passed to the action callback.
123, notify => true ) wp_schedule_event( timestamp, hourly, myplugin_process_post, args ) add_action( myplugin_process_post, myplugin_process_post_callback ) function myplugin_process_post_callback( args ) { post_id = isset( args[post_id] ) ? intval( args[post_id] ) : 0 // Process the post... } ?>
Querying and Managing Scheduled Events
Helpful functions to inspect or manage event schedules:
- wp_next_scheduled( hook, args = array() ) — returns the Unix timestamp for the next occurrence.
- wp_get_schedule( hook, args = array() ) — returns the recurrence string (e.g., hourly).
- wp_unschedule_event( timestamp, hook, args = array() ) — unschedules a specific event at a particular timestamp.
- wp_clear_scheduled_hook( hook, args = array() ) — removes all events for a hook (or matching args).
Best Practices
- Idempotence: Ensure your scheduled callback is safe to run multiple times and can handle failures and retries without corruption.
- Short Tasks: Keep callbacks short. If you have long-running or resource-heavy work, delegate it to a queue, background worker, or separate process. Consider using Action Scheduler or WP-CLI background jobs.
- Duplicate Prevention: Use wp_next_scheduled() and store state (e.g., transient or post meta) if needed to avoid duplicate work.
- Cleanup: Remove scheduled events on plugin deactivation to avoid orphaned cron jobs.
- Monitoring: Use logging or admin plugins like WP Crontrol to view scheduled events and verify execution.
- Security: Validate and sanitize any arguments passed to scheduled tasks as they may come from different code paths.
Reliability and Alternatives
Because WP-Cron depends on site traffic, it may not fire exactly on schedule in low-traffic sites. Conversely, on high-traffic sites WP-Cron can spawn many processes. Consider these alternatives:
- Use server cron to wp-cron.php — disable WP-Cron spawn and call wp-cron.php at regular intervals from server cron (recommended for reliability).
- Use WP-CLI — run scheduled cron events via cron: wp cron event run –due-now.
- Action Scheduler — a robust queueing and scheduling library used by big plugins (WooCommerce). It supports background processing and retries.
- External job queues — RabbitMQ, Redis queues, or external workers for heavy tasks.
How to run wp-cron.php from system cron
Define in wp-config.php: define(DISABLE_WP_CRON, true) Then add a real cron job to hit wp-cron.php at a fixed interval.
# crontab example: run every 5 minutes using curl /5 curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>1 # or using wget /5 wget -q -O - https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>1
Why call with ?doing_wp_cron
This query parameter is used by core to identify an internal run and is recommended when invoking wp-cron.php externally.
Handling Timezones
WordPress stores scheduled timestamps in GMT internally, so be careful when scheduling events at specific local times. Two approaches:
- Relative scheduling: Use time() offset constants (e.g., time() DAY_IN_SECONDS) for relative schedules.
- Specific local times: Use current_time(timestamp) as a base when computing a timestamp that respects the WordPress timezone setting:
Debugging and Tools
- Enable WP debug logs (LOGGING) and call error_log() inside your callbacks to verify execution.
- Use the WP Crontrol plugin to view, edit, run, and delete cron events from the WP admin.
- Use WP-CLI: wp cron event list to list scheduled events and wp cron event run –hook=my_hook to run them manually.
Advanced Topics
Multiple Schedules with Arguments
You can schedule the same hook multiple times with different argument sets. When clearing, match args exactly to avoid unintended removals.
1 ) args2 = array( user_id => 2 ) wp_schedule_event( time() 60, hourly, my_multi_hook, args1 ) wp_schedule_event( time() 120, hourly, my_multi_hook, args2 ) // To clear only user 1 job: wp_clear_scheduled_hook( my_multi_hook, args1 ) ?>
Rescheduling and Updating
If you need to change the timestamp for a specific scheduled event, use wp_reschedule_event() by retrieving the existing timestamp and then calling reschedule. Or unschedule and reschedule a fresh one.
When Cron Callbacks Need More Time
If a scheduled job needs to do heavy processing, do not run it all synchronously in the cron callback. Options:
- Push tasks to a queue (database, Redis) and process via a separate worker.
- Spawn background requests (non-blocking) to a specific admin-ajax endpoint to continue processing.
- Use Action Scheduler or custom WP background processing classes.
Common Pitfalls and How to Avoid Them
- Duplicate scheduling — Always check wp_next_scheduled before scheduling.
- Missing schedules after cache flush — Ensure object cache is persistent or use database-backed cron storage if using non-persistent caching, server cron is recommended.
- Time inaccuracies — Compute timestamps using WP timezone-aware functions when scheduling at local times.
- Slow callbacks — Offload heavy tasks avoid timeouts that could block wp-cron.php.
- Unremoved events — Clear scheduled hooks on deactivation to prevent orphan events.
Security Considerations
- Sanitize and validate arguments passed to scheduled callbacks.
- Do not expose administrative or sensitive operations to guest-invokable endpoints. If using an HTTP endpoint to continue heavy processing, include a secret token and permission checks.
- If executing external HTTP requests from cron tasks, implement timeouts and error handling to avoid hanging wp-cron.php.
Practical Examples Summary
- Recurring hourly task: wp_schedule_event(time() HOUR_IN_SECONDS, hourly, my_hook).
- One-time task at a specific local time: compute timestamp with strtotime(…, current_time(timestamp)) then wp_schedule_single_event().
- Custom 5-minute interval: add filter to cron_schedules and use that key for wp_schedule_event().
- Server cron reliability: define(DISABLE_WP_CRON, true) and add crontab to curl wp-cron.php every N minutes.
Useful Links and Tools
- WordPress Plugin Developer Handbook — Cron API (official documentation)
- WP Crontrol — plugin to inspect and control WP-Cron events from the admin
- WP-CLI cron commands
Conclusion
WP-Cron is a flexible and widely used built-in scheduler for WordPress, ideal for many routine tasks such as cleanup, notifications, and periodic API calls. However, developers must be aware of its quirks: it is traffic-dependent, not always precise, and can be affected by caching and object stores. Use wp_schedule_event and wp_schedule_single_event for recurring and single tasks, add custom intervals when needed, keep callbacks efficient, and consider server cron or robust queue systems for production-level reliability and heavy workloads. For management and debugging, WP Crontrol and WP-CLI are indispensable tools.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |