Skip to content
ThemesIonic — home
WooCommerce

Action Scheduler: Past-Due Actions Found; Something May Be Wrong

The notice appears when a pending action is more than a day overdue. It usually means the queue runner is not being triggered, and the fix is to give it a reliable trigger, not to delete the actions.

5 min read intermediate

"Action Scheduler: N past-due actions found; something may be wrong" means at least one pending action was scheduled to run more than a day ago and still has not. Action Scheduler is the background queue WooCommerce and many plugins use for emails, renewals, webhooks and data updates. A day-old pending action almost never means one bad task. It means the queue runner is not being triggered often enough, or at all.

What the notice checks

The check runs on admin_notices for users who can manage_options. It counts actions with the status pending and a scheduled date older than one day, and shows the notice if the count is at least one. Both numbers are filterable:

add_filter( 'action_scheduler_pastdue_actions_seconds', fn() => 6 * HOUR_IN_SECONDS );
add_filter( 'action_scheduler_pastdue_actions_min', fn() => 5 );

When the check finds nothing, it stores a transient and skips the check for a quarter of the threshold — six hours by default. When it finds past-due actions, it stores nothing and checks again on the next admin page.

The link in the notice opens Tools › Scheduled Actions filtered to "Past-due". With WooCommerce active, the same list is also at WooCommerce › Status › Scheduled Actions.

Keep two other statuses apart. Failed actions ran and threw an error — look at their log entries. Past-due actions never started. This article is about the second.

How the queue normally runs

Current versions of Action Scheduler have two triggers:

  1. WP-Cron. It schedules action_scheduler_run_queue on its own every_minute interval. Each run claims a batch of 25 actions and keeps going for up to 30 seconds (filters: action_scheduler_queue_runner_batch_size, action_scheduler_queue_runner_time_limit).
  2. The async request runner. At the end of an admin request, at most once every 60 seconds, it sends a background request that processes the queue, provided due actions are waiting and the concurrent batch limit — one by default — is not reached. That request re-dispatches itself every few seconds until nothing is due.

Both rely on something hitting the site. WP-Cron only runs on page loads, as WordPress Cron explained describes, and the async runner only on admin page loads.

The trap: the notice can make itself disappear

The notice appears in the admin. Loading an admin page triggers the async runner. So an administrator who logs in to investigate starts the queue just by looking, clicks around for a few minutes, sees the count fall and concludes the problem fixed itself.

It did not. On a store where WP-Cron is not running, the queue only starts when somebody opens wp-admin; the async runner then works until nothing is due and stops. Overnight renewals and morning emails wait until the next login. If past-due actions build up again every night, treat it as a cron problem, not a fluke.

Causes, in order of likelihood

  1. WP-Cron is disabled with nothing replacing it. DISABLE_WP_CRON set to true and no system job. Common after a migration that did not carry the crontab over. Disabling WP-Cron properly has the two-step version.
  2. WP-Cron cannot spawn. A blocked loopback request, Basic Auth, or a firewall rule on wp-cron.php. The async runner uses a loopback too, so both triggers fail together.
  3. The queue is bigger than one runner. A large import, a sale with thousands of orders, or a migration can enqueue more than one batch per minute can clear. Actions run, but not fast enough.
  4. One action blocks the batch. An action that runs into the PHP time limit or a fatal error kills the batch process. Check the log of the oldest past-due action and of recent failed ones.
  5. Page caching hides traffic. If every visitor is served from a full-page cache, PHP never runs for them, so WP-Cron is never triggered.

Fix it

Find out which copy of Action Scheduler is loaded and what the queue looks like:

wp action-scheduler source
wp action-scheduler version
wp action-scheduler status

Process the backlog directly from the command line, where web time limits do not apply:

wp action-scheduler run --batch-size=100 --batches=20

The run command also takes --hooks and --group to process one kind of action first, such as renewals.

Then give the queue a trigger that does not depend on visits. Disable visit-triggered cron in wp-config.php and add a system cron job, every minute or two, that runs all due WordPress events, action_scheduler_run_queue included:

* * * * * cd /var/www/example.com && wp cron event run --due-now --quiet

For a steady backlog, append && wp action-scheduler run --quiet to the same line. Do not run only the Action Scheduler command: with WP-Cron disabled, core's own events, such as scheduled posts and update checks, would have no trigger. For sustained high volume, raise action_scheduler_queue_runner_concurrent_batches cautiously; each extra batch is another PHP process hitting the database. How to speed up WooCommerce covers keeping the actions tables themselves small.

Common mistakes

  • Deleting past-due actions to clear the notice. They are work that has not happened yet.
  • Running wp action-scheduler clean and expecting it to help. By default it deletes only completed and canceled actions older than 31 days.
  • Raising concurrent batches on shared hosting, which turns a slow queue into a slow site.
  • Assuming the problem is solved because the count dropped while you were logged in.

Verify

  • The Past-due view at WooCommerce › Status › Scheduled Actions is empty or shows only actions a few minutes old.
  • wp action-scheduler status shows no growing backlog over a day.
  • The newest completed actions have timestamps from overnight, not only from when you were logged in.
  • The emails and renewals that depended on the queue have gone out.

Frequently asked

They use different cut-offs. The tab counts every pending action whose scheduled time has passed, even by a few seconds, which is normal on a busy store. The admin notice only counts actions more than one day overdue.
Only if you know what they are. They may be subscription renewals, follow-up emails, webhook deliveries or stock updates that have not happened yet. Fix the runner first and let them run; cancel only actions whose hook belongs to a plugin you removed.
WooCommerce bundles it, and many other plugins ship their own copy. Only one copy loads: the newest registered version. Run wp action-scheduler source to see which plugin's copy is active and wp action-scheduler version for its version.

Related guides