Running Action Scheduler at Scale (WP-CLI)
This guide documents the scale-focused knobs exposed by Action Scheduler’s WP-CLI commands and queue runner. All behavior described here is verified in the classes/WP_CLI/ implementation and related runner classes.
Goal
Run Action Scheduler in high-throughput environments using wp action-scheduler run, with explicit control over batching, concurrency, and memory pressure.
Disabling the Async Request Runner
Action Scheduler can dispatch async requests to process actions via ActionScheduler_AsyncRequest_QueueRunner. To run exclusively via system cron + WP-CLI, disable the async request runner.
Two code-level mechanisms are supported by core:
- Disable the async request runner via filter
ActionScheduler_AsyncRequest_QueueRunner::allow() applies the action_scheduler_allow_async_request_runner filter. Returning false prevents async dispatch.
add_filter( 'action_scheduler_allow_async_request_runner', '__return_false' );
- Disable the default
action_scheduler_run_queuehook
The queue runner attaches to the action_scheduler_run_queue hook during initialization. Removing this action disables the default runner. The system status command reports “(disabled)” when the hook is not attached.
remove_action( 'action_scheduler_run_queue', array( ActionScheduler::runner(), 'run' ) );
Tip:
wp action-scheduler statuswill display whether the runner is disabled.
Running via System Cron
Schedule WP-CLI runs through your system cron to process jobs without WP-Cron or async requests.
Example cron entry (every minute)
* * * * * cd /path/to/wordpress && wp action-scheduler run --batch-size=200 --batches=1 --allow-root
CLI syntax
wp action-scheduler run [--batch-size=<size>] [--batches=<size>] [--cleanup-batch-size=<size>] [--hooks=<hooks>] [--group=<group>] [--exclude-groups=<groups>] [--free-memory-on=<count>] [--pause=<seconds>] [--force]
Concurrent Runners
Action Scheduler enforces a maximum number of concurrent batches per store. The queue runner checks this via ActionScheduler_Abstract_QueueRunner::has_maximum_concurrent_batches().
Allow more concurrent batches
Use the action_scheduler_queue_runner_concurrent_batches filter to raise the limit:
add_filter( 'action_scheduler_queue_runner_concurrent_batches', static function () {
return 5;
} );
Override concurrency checks per run
WP-CLI can override the concurrency check using --force:
wp action-scheduler run --force
Note:
--forcebypasses the “too many concurrent batches” error in the WP-CLI queue runner.
Performance Tuning with WP-CLI
Batch size and cleanup size
--batch-size=<size>: Max actions to run per batch (default100).--cleanup-batch-size=<size>: Max actions to clean per batch (default--batch-size).
Freeing memory and pauses
wp action-scheduler run exposes two memory controls that delegate to ActionScheduler_DataController:
--free-memory-on=<count>: Free memory every N actions (default50,0disables).--pause=<seconds>: Seconds to sleep when freeing memory (default0).
Scoping work by hook or group
--hooks=<hooks>: Comma-separated list of hooks to run (no spaces).--group=<group>: Only run actions in a specific group.--exclude-groups=<groups>: Comma-separated list of groups to exclude (ignored if--groupis set).
Examples
# Process only a specific hook
wp action-scheduler run --hooks=wc_update_product_lookup_tables
# Process only one group in larger batches
wp action-scheduler run --group=action-scheduler --batch-size=500
# Exclude a noisy group
wp action-scheduler run --exclude-groups=importer
Cleaning at Scale
Large installations should periodically clean old actions to keep tables lean.
wp action-scheduler clean --status=complete,failed,canceled --before='30 days ago'
CLI syntax
wp action-scheduler clean [--batch-size=<size>] [--batches=<size>] [--status=<status>] [--before=<datestring>] [--pause=<seconds>]