WordPress Development
WordPress WP-Cron Explained: Scheduling Tasks, Fixing Reliability, and Server Cron Setup
WP-Cron powers every scheduled task in WordPress but has critical reliability limitations. Here is how it works, how to use it, and when to replace it with a server cron job.
Simple Automation Solutions
··⌛ 9 min read
WordPress runs scheduled tasks — sending emails, checking for updates, cleaning expired data, processing queued actions — using a system called WP-Cron. Understanding how WP-Cron works and its limitations is essential for any WordPress site with time-sensitive automated processes.
How WP-Cron works
Unlike a traditional server cron job that runs on a fixed schedule regardless of site traffic, WP-Cron is triggered by visitor requests. Every time a page is loaded on your WordPress site, WordPress checks whether any scheduled tasks are due to run and executes them if so.
This design has an important consequence: WP-Cron only runs when someone visits your site. On low-traffic sites, scheduled tasks may run hours late if no visitors trigger them at the scheduled time. On high-traffic sites, WP-Cron checks run on every page load, which adds overhead.
What WP-Cron is used for
- WordPress core: checking for core, plugin, and theme updates; clearing expired transients; sending scheduled post notifications
- WooCommerce: processing pending orders, sending order follow-up emails, clearing expired coupons, regenerating product lookup tables
- Email marketing plugins: sending queued emails in batches, syncing subscriber data with external platforms
- Backup plugins: UpdraftPlus and similar plugins use WP-Cron to trigger scheduled backups
- Custom plugins: any custom functionality that needs to run on a schedule (reports, data syncs, cache warming)
Scheduling custom tasks with WP-Cron
Add custom scheduled tasks using two WordPress functions:
Use wp_schedule_event() to register a recurring event. Parameters: timestamp for first run, recurrence interval (hourly, twicedaily, daily, or custom interval), and a hook name. Hook this to a plugin activation or init action.
WordPress provides hourly, twicedaily, and daily intervals by default. Add custom intervals (every 15 minutes, every 6 hours) using the cron_schedules filter.
Use add_action() to attach your callback function to the hook name you registered. This function runs when the cron event fires.
Use the WP Crontrol plugin to see all scheduled cron events in your WordPress admin. Verify your event appears with the correct recurrence and next run time.
Use wp_clear_scheduled_hook() in your plugin deactivation hook to remove the scheduled event when the plugin is deactivated. Orphaned cron events from deactivated plugins are a common cause of unnecessary WP-Cron overhead.
WP-Cron reliability problems and solutions
The visitor-triggered nature of WP-Cron creates reliability issues that affect many WordPress sites:
| Problem | Symptom | Solution |
|---|---|---|
| Low traffic site | Scheduled tasks run hours late | Replace with server cron (see below) |
| High traffic site | Cron checks on every page load adds overhead | Disable WP-Cron and use server cron |
| Overlapping cron jobs | Multiple instances of same job run simultaneously | Use a cron locking plugin or transient-based lock |
| Failed cron jobs | Task runs but encounters PHP error | Check error logs; use WP Crontrol to manually trigger and debug |
| Missed backups | UpdraftPlus backup missed its schedule | Usually a WP-Cron reliability issue — switch to server cron |
Setting up a real server cron job
The most reliable solution for WP-Cron problems is to disable WordPress cron and replace it with a real server cron job that runs on a fixed schedule regardless of traffic:
Add define('DISABLE_WP_CRON', true); to wp-config.php before the ‘stop editing’ line. This prevents WordPress from triggering cron on page loads.
Access your server via SSH or your hosting control panel cron section. Add a cron job that runs every 5 minutes: */5 * * * * wget -q -O - https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
If WP-CLI is available on your server: */5 * * * * cd /path/to/wordpress && wp cron event run --due-now --path=/path/to/wordpress >/dev/null 2>&1. WP-CLI is more efficient as it skips the HTTP request overhead.
After setting up server cron, use the WP Crontrol plugin to verify that cron events are running at their scheduled times. Check your backup plugin to confirm backups are completing on schedule.
Useful WP-Cron plugins
WooCommerce uses Action Scheduler (an open-source library by Automattic) for all its scheduled tasks rather than standard WP-Cron. Action Scheduler provides persistent storage of queued actions, retry logic on failure, and concurrent processing. For any plugin handling high-volume background tasks (bulk email sending, API syncs, order processing), Action Scheduler is the correct foundation.
Need custom WordPress automation or scheduled task development?
Simple Automation Solutions builds custom WordPress automation, WP-Cron implementations, and background task systems for businesses worldwide.
Frequently asked questions
Should I disable WP-Cron on every WordPress site?+
Only if you have reliable server cron access and a reason to disable it. For most standard WordPress sites with moderate traffic, WP-Cron works adequately. Disable it and switch to server cron when: your site has very low traffic and scheduled tasks are frequently late; you have high traffic and the per-request cron check is measurably impacting performance; or you have time-critical background tasks (payment processing, compliance-related scheduling) that cannot tolerate variable execution timing.
Why are my UpdraftPlus backups not running on schedule?+
Almost always a WP-Cron reliability issue. The backup is triggered by WP-Cron, which requires a visitor request to fire. If your site has no visitors at the scheduled backup time (common for 3 AM backups on low-traffic sites), the backup does not run until the next visitor. Solution: disable WP-Cron and set up a server cron job or use an external cron service (cron-job.org) to reliably trigger cron at the scheduled time.
How do I debug a WP-Cron job that is not running?+
Install WP Crontrol and go to Tools › Cron Events. Find your event in the list and note its next scheduled run time. If it shows as overdue, click Run Now to manually trigger it. If it runs successfully, the issue is cron timing (use server cron). If it shows an error, click the error to see the PHP error that prevented execution — fix the underlying code issue. If the event does not appear in the list at all, the scheduled event was never registered or was cleared — review your plugin activation hook and registration code.
Simple Automation Solutions is a global digital product studio specialising in WordPress and Bubble.io. We serve founders, startups, and businesses worldwide — delivering production-ready websites built to rank, convert, and scale.
