By Brent Shepherd January 23, 2019
To improve performance, WooCommerce processes many operations in the background. Webhooks, subscription payments, and sometimes emails are all processed outside of the requests that serve site visitors.
By default, this background processing is initiated by WP Cron and run within the context of a web request. This works well for most WooCommerce stores.
Once a WooCommerce store scales, particularly in order volume, it can become necessary to increase WooCommerce’s background processing throughput. Starting with WooCommerce 3.5.0, there is a new, configurable job queue library which makes this possible. This library, named Action Scheduler, also includes WP CLI commands to make it possible to do background processing outside a web request.
This post explores:
The limits of background processing within WP Cron requests
The benefits of using WP CLI for background processing, and
How to run WooCommerce background tasks via Terminus on Pantheon.
Background Processing with WP Cron
Processing background jobs with WP Cron is a good default option for WordPress plugins, which is why it’s the default in WooCommerce. As WordPress itself and many other plugins rely on WP Cron, more hosts support it than any other method.
However, as WP Cron runs within the context of a web request, it is constrained to the time limits provided to web requests. Pantheon provides a maximum execution time of 120 seconds for web requests. That means a WP Cron request can process a queue of jobs for an absolute maximum of 2 minutes.
To compound the issue of time limits, WP Cron is only initialized by web traffic; someone visiting your site. Aside from predictability, this can also cause problems for both low and high-traffic sites.
there can be a significant gap in time between each request that processes the queue; and
no more than one request processes the queue at a time, i.e. no concurrency.
These are not issues when processing moderately sized queues, for example, a queue of a few thousand jobs. However once dealing with queues of 10s or 100s of thousands, it becomes necessary to go beyond these defaults to increase throughput.
Increasing WP Cron Background Processing Throughput
To maximize compatibility with all hosting environments, Action Scheduler runs with conservative defaults. For example, it only processes a queue of jobs for a maximum of 30 seconds.
Pantheon provides more resources than your average WordPress host, so without too much effort, we can comfortably increase WooCommerce’s background processing throughput on Pantheon.
Achieving this increase can be as simple as installing the Action Scheduler High Volume plugin.
This plugin provides example code to increase:
time allocated to processing the queue
number of concurrent queues to run via loopback requests
One quick win is to increase the amount of time allocated to queues. On Pantheon, we know a default of 120 seconds is available, so we can safely increase the default of 30 to something much higher. I recommend increasing it to 90 seconds.
The highest impact change is to process concurrent queues. The High Volume plugin makes asynchronous requests to the server to process additional queues each time WP Cron runs Action Scheduler’s queue. Instead of one queue being run only in that request, 2 or more can run. The High Volume plugin makes 5 loopback requests, to process 6 concurrent queues.*
Depending on the operations performed in the background jobs, especially database operations, these two changes can provide a linear increase. That means by installing the High Volume plugin to triple the timeout and add 5 loopback requests, you can see up to a 15x increase in throughput of tasks processed in the background.
Background Processing with WP CLI via Terminus
Once a WooCommerce store grows to a significant scale, even a 15x increase in throughput is not sufficient to handle the queue of background jobs.
While it’s possible to further increase the Action Scheduler configuration on WP Cron for higher throughput, by increasing the number of loopback requests and increasing other options to squeeze out small gains, I don’t recommend that method.
Instead, I recommend using Terminus to process background tasks.
There are many benefits to handling queues with Terminus, including:
Prioritize certain jobs or groups of jobs, like process payments faster than webhooks
Override default queue concurrency
A more accurate, configurable rate of queue initialization
Some of these benefits are available by default. The Action Scheduler WP CLI documentation provides the parameters needed to achieve some of these configurations.
Running Action Scheduler via Terminus
Processing background jobs via Terminus is as simple as running the following command:
terminus wp example.live -- action-scheduler run
When running that command, you should receive output similar to this:
If you have no jobs awaiting processing, you instead see something similar to this:
For a real example, let's look at AutomateWoo.com, which runs on Pantheon and uses WooCommerce to sell WooCommerce plugins on subscription. For that site, we can run the following Terminus command:
terminus wp automatewoo.live -- action-scheduler run --batches-size=5 --batches=0
The execution of that command looks something like this:
Scheduling Terminus via Cron
There is one glaring problem with this - it requires running the queue manually. Scheduling the command in Crontab on another machine (or two, for redundancy) is an effective way to automate it.
For example, we have this Cron job setup to run the job queues on AutomateWoo.com:
*/1 * * * * /usr/local/bin/terminus wp automatewoo.live -- action-scheduler run --batch-size=10 --batches=0 >> /logs/AutomateWoo/terminus/action-scheduler-run.log 2>> /logs/AutomateWoo/terminus/action-scheduler-run-error.log
You may notice that crontab entry includes output logging so that if things go wrong, we can trace the issue, something I highly recommend.
Depending on where and how you run the Cronjob, you may need to make sure the machine’s SSH config file supports SSH authentication for Terminus when running via crontab.
To do that, you can set up the IdentityFile and IdentitiesOnly options in your config like this:
For AutomateWoo.com, we also use a unique key for Terminus / Pantheon, so our config looks like this:
Battle-tested Background Processing with Terminus
As part of our Subscribe.me service, we use WP CLI processing like this to help large WooCommerce Subscriptions stores process queues of over 50,000 renewal orders every month. With 10-15 concurrent queues, we operate with a sustained rate of close to 10,000 orders / hour without impacting front-end site performance.
The same techniques can be used to process large queues of WooCommerce webhooks, or tasks from other popular WooCommerce plugins, like Follow-ups and Memberships.
*please note, this means each time WP Cron triggers Action Schedulers hook, you will be hitting your server with additional requests. If you only have large queues intermittently, say one day per month, we recommend only increasing this value for that period, or better yet, running actions via Terminus.
You may also like:
- [BLOG] Migrating Your WooCommerce Site to Pantheon
- [WEBINAR] Maintaining Your WooCommerce Website
- [WEBINAR] WordPress 5.0: What's New?