WordPress runs background tasks (publishing scheduled posts, checking for updates, sending emails, plugin maintenance, WooCommerce jobs) through WP-Cron, a list of scheduled events stored in the database. When scheduled posts miss their time, emails aren’t sent, or the site slows down because of a runaway task, the first step is to look at the cron event list.
For running WP-Cron reliably from the system cron, see WordPress real cron.
List all scheduled events
With WP-CLI, from the WordPress root:
wp cron event list
+------------------------------------+---------------------+-----------------------+------------+
| hook | next_run_gmt | next_run_relative | recurrence |
+------------------------------------+---------------------+-----------------------+------------+
| wp_version_check | 2026-10-14 14:02:11 | 3 hours 12 minutes | 12 hours |
| woocommerce_cleanup_sessions | 2026-10-14 11:30:00 | 40 minutes | 12 hours |
| action_scheduler_run_queue | 2026-10-14 10:51:00 | now | 1 minute |
| my_plugin_hourly_sync | 2026-10-14 10:20:05 | 30 minutes ago | 1 hour |
Useful variations:
wp cron event list --fields=hook,next_run_relative,recurrence --format=table
wp cron event list --next_run_relative=now # overdue events
wp cron schedule list # available intervals (hourly, twicedaily, daily, custom)
wp cron test # can WP-Cron spawn at all?
See WP-CLI.
Without WP-CLI: the WP Crontrol plugin shows the same list in Tools → Cron Events, and lets you run, edit and delete events.
Read the list: what to look for
- Overdue events (“30 minutes ago”): WP-Cron isn’t running often enough. That’s typical on low-traffic sites, or when
DISABLE_WP_CRONis set without a system cron replacement. - Unknown hooks: find their source (below). Leftovers from removed plugins can be deleted.
- Duplicate events: the same hook scheduled many times, which is a plugin bug. That causes repeated work and database bloat.
- Very frequent events (every minute) from plugins you don’t need.
Find which plugin owns a hook
grep -rn "my_plugin_hourly_sync" wp-content/plugins/ wp-content/themes/ wp-content/mu-plugins/ | head
The add_action('hook_name', …) line shows which code runs, and wp_schedule_event shows where it was scheduled.
Run, schedule or delete events
wp cron event run my_plugin_hourly_sync # run now (good for testing)
wp cron event run --due-now # run everything that's due
wp cron event delete old_plugin_hook # remove all events for a hook
wp cron event schedule my_hook now hourly # schedule a hook
Deleting an event of an active plugin is temporary. It usually reschedules itself. Disable the feature in the plugin, or remove the plugin.
Clean up cron bloat
The full schedule is stored in a single option, cron, in wp_options. It’s autoloaded on every request. Thousands of stale or duplicate events make it huge:
wp option get cron --format=json | wc -c # size in bytes
wp cron event list --format=count
If it’s very large, back up the database, remove events for hooks that no longer exist, and fix the plugin creating duplicates. See WordPress autoloaded options.
WooCommerce and the Action Scheduler
WooCommerce and many plugins use the Action Scheduler library for heavier background work (emails, webhooks, subscription renewals). It has its own queue tables, triggered by WP-Cron or WP-CLI:
- Tools → Scheduled Actions shows pending, failed and completed actions;
- run the queue from the system cron for reliability:
wp action-scheduler run; - clean up old completed actions if the tables grow (retention settings, or WP-CLI cleanup commands).
Make WP-Cron reliable
Default WP-Cron only runs when someone visits the site, and spawns on page loads, which adds latency for some visitors. On a VPS, run it from the system cron instead:
// wp-config.php
define('DISABLE_WP_CRON', true);
*/5 * * * * cd /var/www/example.com/public && wp cron event run --due-now --quiet
Full guide: WordPress real cron. See also crontab.
Quick reference
| Task | Command |
|---|---|
| List events | wp cron event list |
| Overdue | wp cron event list --next_run_relative=now |
| Run due events | wp cron event run --due-now |
| Run one hook | wp cron event run HOOK |
| Delete a hook | wp cron event delete HOOK |
| Schedules | wp cron schedule list |
| Test spawning | wp cron test |
| GUI | WP Crontrol plugin |
Related: WordPress white screen and WordPress on a VPS.