woocommerce Case study
Action Scheduler Core
This is the MU-plugin that brought WooCommerce background processing under control on the store I run. One file, mu-admin-as-core.php, now owns every Action Scheduler and admin-speed setting, so the whole policy is reviewable in one place.
The business problem
Pending jobs in Action Scheduler had piled up to roughly 38,000 on our WooCommerce store. Queue runners fired during ordinary web requests, WC Admin analytics kept scheduling imports nobody read, and staff felt it as a dashboard that stalled at random. Background work was competing with the people actually running the store.
What I delivered
- A single consolidated file, mu-admin-as-core.php, replacing Action Scheduler and admin-speed tweaks that had been scattered across older configs.
- Queue runner limits set through core filters: batch size 10, one concurrent batch, a 20-second time limit and a 7-day retention period for finished actions.
- The async request runner switched off, and the web-request queue runner disabled whenever DISABLE_WP_CRON is set, so jobs execute only from server cron.
- A daily cleanup that unschedules leftover WC Admin actions such as wc_admin_daily and wc_admin_import_orders.
- Admin-side relief: heartbeat throttled to 60 seconds and deregistered outside the editor, product and order lists capped at 20 rows, heavy taxonomy columns stripped from the product table.
Technical approach
- Everything goes through documented filters like action_scheduler_queue_runner_batch_size and action_scheduler_retention_period, with no patched core or plugin code.
- woocommerce_admin_disabled turns off the React analytics suite, which was the main producer of scheduled work we never used.
- The unschedule pass is throttled with a site transient so it runs at most once per day instead of on every request.
- Tuning numbers live as class constants at the top of A2_Admin_AS_Core, so adjusting a limit is a one-line change that ships through git.
Result and evidence
The pending queue dropped from about 38,000 actions to 4,900 once the tuning and cleanup settled, an 87 percent reduction, and it has held at that level. Admin pages stopped waiting behind background batches.
Commercial value
A back office that responds quickly keeps a 12-person online team on actual work instead of watching spinners, which makes this small file one of the highest-return changes on the platform.
Readable implementation brief
implementation_brief {
project: "Action Scheduler Core"
file: "mu-plugins/mu-admin-as-core.php (one consolidated file)"
before: "~38,000 pending actions"
after: "~4,900 and holding (87% reduction)"
queue_limits: "batch size 10, 1 concurrent batch,
20s time limit, 7-day retention"
runners: "async request runner off; web-request runner
disabled when DISABLE_WP_CRON is set"
execution: "server cron only, never inside a page request"
cleanup: "daily unschedule of leftover WC Admin actions
(wc_admin_daily, wc_admin_import_orders)"
}What this project shows
The fix was configuration, not code: batch size, concurrency, a time limit, retention, and moving execution to server cron. Knowing which filters to set is the whole job.
Consolidating scattered tweaks into one readable file mattered as much as the values themselves. Performance settings spread across four places are settings nobody will dare change later.