Usage | Admin | WP-CLI | Background Processing at Scale | API | FAQ | Version 3.0


A scalable, traceable job queue for background processing large queues of tasks in WordPress. Designed for distribution in WordPress plugins - no server access required.


Action Scheduler has custom WP CLI commands available for processing actions.

For large sites, WP CLI is a much better choice for running queues of actions than the default WP Cron runner. These are some common cases where WP CLI is a better option:

With a regular web request, you may have to deal with script timeouts enforced by hosts, or other restraints that make it more challenging to run Action Scheduler tasks. Utilizing WP CLI to run commands directly on the server give you more freedom. This means that you typically don’t have the same constraints of a normal web request.

If you choose to utilize WP CLI exclusively, you can disable the normal WP CLI queue runner by installing the Action Scheduler - Disable Default Queue Runner plugin. Note that if you do this, you must run Action Scheduler via WP CLI or another method, otherwise no scheduled actions will be processed.


These are the commands available to use with Action Scheduler:

The best way to get a full list of commands and their available options is to use WP CLI itself. This can be done by running wp action-scheduler to list all Action Scheduler commands, or by including the --help flag with any of the individual commands. This will provide all relevant parameters and flags for the command.

Cautionary Note on Action Dependencies when using --group or --hooks Options

The --group and --hooks options should be used with caution if you have an implicit dependency between scheduled actions based on their schedule.

For example, consider two scheduled actions for the same subscription:

Under normal conditions, Action Scheduler will ensure the scheduled_payment action is run before the scheduled_expiration action. Becuase that’s how they are scheduled.

However, when using the --hooks option, the scheduled_payment and scheduled_expiration actions will be processed in separate queues. As a result, this dependency is not guaranteed.

For example, consider a site with both:

If two queue runners are running alongside each other with each runner dedicated to just one of these hooks, the queue runner handling expiration hooks will complete the processing of the expiration hooks more quickly than the queue runner handling all the payment actions.

Because of this, the --group and --hooks options should be used with caution to avoid processing actions with an implicit dependency based on their schedule in separate queues.

Improving Performance with --group or --hooks

Being able to run queues for specific hooks or groups of actions is valuable at scale. Why? Because it means you can restrict the concurrency for similar actions.

For example, let’s say you have 300,000 actions queued up comprised of:

Action Scheduler’s default WP Cron queue runner will process them all together. e.g. when it claims a batch of actions, some may be emails, some membership updates and some renewals.

When you add concurrency to that, you can end up with issues. For example, if you have 3 queues running, they may all be attempting to process similar actions at the same time, which can lead to querying the same database tables with similar queries. Depending on the code/queries running, this can lead to database locks or other issues.

If you can batch based on each action’s group, then you can improve performance by processing like actions consecutively, but still processing the full set of actions concurrently.

For example, if one queue is created to process emails, another to process membership updates, and another to process renewal payments, then the same queries won’t be run at the same time, and 3 separate queues will be able to run more efficiently.

The WP CLI runner can achieve this using the --group option to create queue runners that focus on a specific group and, optionally, the --exclude-groups option to create one or more ‘catch-all’ queue runners that ignore those groups.