Skip to content

WP-Cron

VIP’s cron infrastructure leverages WP-Cron provided by WordPress Core, and cron jobs are initiated and regulated by Automattic’s Cron Control plugin. VIP’s Cron Control provides an optimized SQL table for WordPress Cron events. This approach satisfies the highly concurrent querying commonly seen on VIP sites. Each named event in the queue is handled in parallel with other events, allowing for a large event handling capacity. The VIP cron system orchestrates the activity of the event workers in the different containers, to avoid conflicts with two workers processing the same event.

Cron jobs are best suited for:

  • Any intensive processing task such as syndicating content between sites or ingesting videos from third-party video services.
  • Tasks that are not required to run in real-time such as publishing a post at a future date.
  • Any task that might require more than 300 seconds to complete.

Limitations

Running WP-CLI commands (including custom WP-CLI commands) inside a cron action by calling WP_CLI::runcommand() will not work. Instead, the logic and functionality of a WP-CLI command should be added into a custom function, and that function can be scheduled as a cron event.

The difference between VIP cron and WP-Cron

The core WP-Cron relies on page requests to check, schedule and execute a single cron job. This is less than ideal in cached environments where page requests might not reach the origin server. If the page request does reach the origin server it might not be at the specified time and more importantly, it will create an additional page load for that request as a potentially resource-intensive cron job executes. Since the core WP-Cron control can only execute one cron event at a time (every 1 minute), long-running jobs will further delay subsequent cron jobs from running at their scheduled times, potentially creating an everlasting backlog of scheduled tasks. In addition, the cron jobs are stored in the alloptions which can be problematic if alloptions grows to be over 1MB in size.

The VIP cron system solves the limitations of the core WP-Cron by:

  • Storing cron jobs in the wp_a8c_cron_control_jobs custom table instead of alloptions.
  • Having a dedicated VIP cron runner that checks for jobs that are due to be executed at a polling interval of 30 seconds instead of relying on a page request.
  • Executing cron jobs in separate dedicated containers to alleviate any additional load to the application.
  • Providing the ability to run multiple jobs in parallel instead of one at a time with a maximum of 60 an hour.

Monitoring cron jobs

The VIP cron system is monitored using a series of dedicated authenticated REST API endpoints on each VIP environment. Monitoring ensures that event queues remain within acceptable parameters, that the events within the queue are executed in a timely manner, and that execution is proceeding smoothly.

In addition, cron jobs for a site can be monitored:

Interacting with cron via code

The VIP cron system is built on top of core WP-Cron and uses the same scheduling and unscheduling hooks as the document in the Plugin Handbook:

Note

Do not schedule recurring events using wp_schedule_single_event repeatedly. Use wp_schedule_event instead.

Interacting with Cron via WP-CLI

Use the wp cron WP-CLI command with VIP-CLI to list, run, schedule, unschedule, and delete cron events.

Concurrency

By default, Cron Control will only run one event of a given type (i.e. with the same action) at any one time. This is designed to avoid issues where multiple events running simultaneously write to the same values in the database, particularly in alloptions, causing issues related to data loss.

There can also be improved efficiency when multiple actions are combined to run as one job rather than run as separate cron events.

Increasing Cron Event Concurrency

Before increasing concurrency for a Cron event, first assess:

  • If a Cron event writes data to an option which is autoloaded, it is not safe for increased concurrency.
  • If low numbers of Cron events are expected at any one time, i.e. less than 5, then it is not beneficial to increase concurrency.

To specify the concurrency level for an event, filter the a8c_cron_control_concurrent_event_whitelist hook. Add the event to the array using the action name as the key. Then, specify an integer that represents the number of events of that action that can be run concurrently.

In the code example below, my_async_send_ping is the action name and the integer 10 is assigned to the number of possible concurrent events:

# Increase Cron Control's concurrency limit for my_async_send_ping action to 10
add_filter( 'a8c_cron_control_concurrent_event_whitelist', function( $wl ) {
    $wl['my_async_send_ping'] = 10;
    return $wl;
} );

Last updated: May 13, 2024

Relevant to

  • WordPress