Action Scheduler is the background task engine quietly powering a large share of WooCommerce’s async operations — subscriptions, refunds, stock sync, webhook delivery, abandoned cart emails — and when its internal “claims” mechanism gets stuck, all of those processes can grind to a halt with no obvious error message. Understanding why claims get orphaned in the first place is the key to actually fixing it, rather than just deleting stuck rows and hoping the problem doesn’t come back.
What a “Claim” Actually Is
Before Action Scheduler runs a batch of scheduled tasks, it “claims” a group of pending actions by marking them with a claim ID in its database tables. This claiming mechanism exists to prevent the same action from being picked up and executed twice if multiple queue runners happen to fire at the same time. Once a claimed action completes successfully, the claim is released and the action’s status updates accordingly. The problem arises when that release step never happens.
Why Claims Get Orphaned
A claim becomes “stuck” when the process that claimed a batch of actions dies, times out, or crashes before it can properly release them. A few common causes:
- A fatal error inside a specific callback — if one action in a claimed batch triggers a PHP fatal error, it can freeze the entire batch mid-processing, leaving every other action in that claim stuck in an “in-progress” state indefinitely
- PHP execution timeouts, particularly on shared hosting with restrictive time limits, cutting off a batch before it finishes processing
- Overlapping queue runners, where multiple processes attempt to claim and run actions simultaneously, sometimes from WP-Cron firing more than expected
Once a claim is orphaned this way, Action Scheduler has no automatic way of knowing the original process is dead — it simply sees an active claim and won’t reprocess those actions, or claim new ones past a certain limit, until that stale claim is cleared.
The Underlying Cause Is Often WP-Cron Itself
A significant share of “stuck” Action Scheduler problems trace back to how the queue gets triggered in the first place. By default, Action Scheduler relies on WP-Cron, which itself depends on site visitor traffic to fire scheduled events. On low-traffic sites, or sites where WP-Cron has been disabled or is being throttled by a caching or security plugin, the queue simply doesn’t get triggered reliably enough to process its backlog, and pending actions pile up until they’re flagged as past-due.
How to Check What’s Actually Stuck
Before making any changes, look at what’s currently claimed and pending. In the WordPress admin, go to:
WooCommerce > Status > Scheduled Actions
This shows pending, in-progress, and failed actions, including which specific hooks are affected. If you have SSH access, WP-CLI gives a more precise view of what’s failing and why:
wp action-scheduler list --status=failed --hook --fields=hook,args,last_attempt_gmt --format=table --orderby=last_attempt_gmt --order=DESC
The hook column here tells you exactly which callback is causing failures, which matters if the same action keeps freezing the queue repeatedly rather than just failing once.
Releasing Orphaned Claims
If actions have been sitting “in-progress” for an unreasonably long time — typically more than an hour, since most legitimate actions complete well within that window — releasing those stale claims back to pending status is usually the fastest fix. This is generally done through a direct database update reverting claimed, long-running actions back to pending and clearing the orphaned claim rows, after which the queue runner can pick them back up normally. Always back up your database before running any direct database changes, and if you’re not confident writing that update yourself, consult a developer or the Action Scheduler documentation rather than guessing at the syntax.
Fixing WP-Cron Reliability
Since inconsistent WP-Cron triggering is such a common root cause, a more durable fix is disabling WordPress’s default visitor-triggered cron and replacing it with a real system cron job that fires reliably on a schedule, independent of site traffic. A one-minute interval is generally sufficient to keep the queue moving continuously. Many managed WordPress hosts, including WP Engine and Kinsta, have system cron built in already — in those cases, you typically just need to disable the “alternate WP-Cron” toggle in your hosting dashboard rather than setting anything up manually.
Finding and Disabling a “Poison Pill” Action
If the queue keeps freezing after a few batches despite fixing WP-Cron, there’s likely a specific action consistently triggering a fatal error and repeatedly jamming the claim mechanism. Once you’ve identified the offending hook through the WP-CLI failed-actions list, you can address it by fixing the underlying code issue if it’s from a custom integration, or deleting the specific stuck action if it’s non-critical (tracking-only hooks, for example, are generally safe to remove without affecting orders or payments).
What’s Changing in Action Scheduler 4.0.0
It’s worth knowing that Action Scheduler 4.0.0, bundled with WooCommerce 11.0, specifically targets the underlying database growth problem that contributes to some of these performance issues — tightening retention of failed actions and improving cleanup so tables don’t grow faster than the system can manage on high-volume stores. If you’re running an older version and dealing with recurring claim issues, updating is worth factoring into your troubleshooting, alongside the fixes above rather than as a replacement for them.
Join The Discussion
Have you run into stuck Action Scheduler claims on your own WooCommerce site, and what ended up resolving it? Share whether the fix was a WP-Cron replacement, a specific poison-pill hook you tracked down, or something else entirely. If you’re currently troubleshooting a stuck queue, feel free to ask questions — there’s a good chance someone here has dealt with the exact hook or error you’re seeing.