Complete Guide to Scheduled Events with Subscriptions

Scheduled Events Overview ↑ Back to top

Scheduled events are actions that happen at particular times. WP-Cron and Action Scheduler are systems that trigger and run events. Both of these systems run in the background. Action Scheduler excels at batch processing, storing the actions, error logging, and providing an interface for interacting with the system.

WP-Cron ↑ Back to top

WP-Cron is WordPress’s version of cron, a system to run time-based actions in unix systems. WP-Cron makes it so that third-parties don’t have to concern themselves with specific operating system implementations of cron.

The way WP-Cron works is that on page load, any events that are scheduled for that time or that are waiting from before that time are processed. This means that on a site with low traffic, events might not run at their scheduled time. The initiating action is the page load, and all the waiting events cascade from that initial trigger.

All scheduled jobs with WP-Cron are stored in a single row of the wp_options table. This means that on sites with tens of thousands of scheduled actions the system, all data is being stored in a single column of the database. This creates a number of issues including:

  1. It’s not possible to query scheduled events via MySQL, it must be done in PHP, slowing down querying scheduled events.
  2. Modifying a single scheduled event requires saving or updating all events, slowing down database operations.

Action Scheduler ↑ Back to top

To overcome the scaling issues posed by WP-Cron, Action Scheduler was developed. Action Scheduler creates queues of events that need to be processed and sets its own event that must still be triggered by WP-Cron. When this event is triggered, the queues of events are processed in the background. Action Scheduler can run batches and concurrent queues. On sites with large numbers of actions, this is very helpful.

Action Scheduler also offers an interface to interact with scheduled events and a way to trace event histories.

Debugging WP-Cron ↑ Back to top

Check if WP-Cron has stopped or only Action Scheduler ↑ Back to top

When dealing with events that are no longer occurring, one question to ask is whether WP-Cron has stopped or Action Scheduler. In order to determine if one or the other has stopped, their last working dates will need to be found and checked.

To check WP-Cron:

  1. Install the WP Crontrol extension. This extension provides a way to view the WP-Cron system.
  2. Go to Tools > Cron Events.
  3. In the Next Run column, check the date for the top entry. Note that the date might have “(now)” added next to it if it is in the past.
Cron Events Next Run Column
Cron Events Next Run Column

To check Action Scheduler:

  1. Go to Tools > Scheduled Actions.
  2. Choose the Complete type and click the heading of the Scheduled Date column to sort by most recent.
  3. Check the Scheduled Date column for the date of the last completed scheduled action.
Scheduled Date of Last Complete Scheduled Action
Scheduled Date of Last Complete Scheduled Action

To determine which system has stopped:

  1. Compare the WP-Cron date with the Action Scheduler date.
  2. If the WP-Cron date is in the past and is before or coincides with the Action Scheduler date, then WP-Cron has been disabled.
  3. If the WP-Cron date is recent, such as in the last few minutes, and after the Action Scheduler date, then Action Scheduler is blocked.

Why has WP-Cron stopped? ↑ Back to top

It is possible that there was a job in the WP-Cron queue that could never complete, causing WP-Cron to go through an endless loop and effectively be blocked from processing more actions.

Here is a sequence of possible events that would block the queue:

  1. The offending job gets to the top of the queue.
  2. WP-Cron runs the offending job.
  3. The job causes a fatal error.
  4. WP-Cron does not remove that job from the queue, because the job was terminated before it had finished.
  5. Return to step 2 and repeat.

To determine the cause of this error, check the Fatal Errors log in WooCommerce > Status > Logs. Look for a fatal error coinciding with the time WP-Cron was last working.

How do I get WP-Cron working again? ↑ Back to top

If you have identified the source of the problem, that source will need to be fixed for WP-Cron to continue working. In the case of a plugin that produced a fatal error, update the plugin to see if a fix has been implemented.

How will this affect WooCommerce Subscriptions? ↑ Back to top

When reinstating WP-Cron, you do not need to clear out or regenerate Subscriptions-related events. Action Scheduler has those events safely stored in a queue waiting to be run. This means that all the actions, such as renewal payments, that would have run since WP-Cron stopped working are still waiting to process. Be aware of how long WP-Cron has been stalled and what that backup means in terms of the events waiting and for your customers.

Scheduled Events with WooCommerce Subscriptions ↑ Back to top

Why does Subscriptions need a working WP-Cron? ↑ Back to top

Subscriptions requires a working WP-Cron because Action Scheduler, the system used to process scheduled events, relies on WP-Cron. Without the initial event triggered by WP-Cron, the rest of the queue in Action Scheduler cannot be processed.

Subscriptions Scheduled Events ↑ Back to top

woocommerce_scheduled_subscription_payment

Scheduled: When a subscription is purchased.

Rescheduled: When a subscriptions status is changed to active. When the next payment date is updated if the subscription has an active status.

Unscheduled: When a subscription’s status is changed to pending-cancel, cancelled, switched, expired or trash.

Run: At the next payment date.

Date type: next_payment.

Arguments: Subscription ID.

woocommerce_scheduled_subscription_trial_end

Scheduled: When a subscription item with a free trial is purchased.

Rescheduled: When a subscriptions status is changed to active. When the trial end date is updated if the subscription has an active status.

Unscheduled: When a subscription’s status is changed to pending-cancel, cancelled, switched, expired or trash.

Run: At the end of a free trial.

Date type: trial_end.

Arguments: Subscription ID.

woocommerce_scheduled_subscription_payment_retry

Scheduled: When the payment_retry date is updated, after a renewal payment has failed.

Rescheduled: When a subscription’s status is changed to active. When the next payment date is updated.

Unscheduled: When a subscription status is changed to pending-cancel, cancelled, switched, expired or trash. When the status changes if the new status is not the same as the retry’s expected status.

Run: According to retry rules; default rules have the first retry 12 hours after failed renewal attempt.

Date type: payment_retry.

Arguments: Last renewal order ID.

woocommerce_scheduled_subscription_expiration

Scheduled: When a subscription is purchased. It will be 0 unless the subscription has an expiration date, i.e. a length.

Rescheduled: When a subscription status is changed to active. When the next payment date is updated if the subscription has an active status.

Unscheduled: When a subscription’s status is changed to pending-cancel, cancelled, switched, expired or trash.

Run: At the end of the subscription length.

Date type: end.

Arguments: Subscription ID.

woocommerce_scheduled_subscription_end_of_prepaid_term

Scheduled: When a subscription is cancelled and its status is changed to pending-cancel.

Rescheduled: When a subscription’s status is changed to pending-cancel.

Unscheduled: When a subscription’s status is changed to active, cancelled, switched, expired or trash.

Run: At the end of the subscription’s prepaid term, when it moves to cancelled status.

Date type: end.

Arguments: Subscription ID.

woocommerce_subscriptions_privacy_anonymize_ended_subscriptions

Scheduled: Hooked onto woocommerce_cleanup_personal_data.

Run: Daily.

Arguments: None.

Notes: This action will not do anything if the setting to cleanup ended subscriptions is not set.

woocommerce_subscriptions_privacy_anonymize_subscription_orders

Scheduled: For each ended subscription which needs to be anonymized.

Run: Immediately when subscription is anonymized.

Arguments: Subscription ID.

woocommerce_subscriptions_privacy_anonymize_subscription_order

Scheduled: For each ended subscription which needs to be anonymized.

Run: Immediately when subscription is anonymized.

Arguments: Subscription ID. 

wcs_report_update_cache 

Scheduled: After a cache-invalidating event and before PHP shutdown.

Run: On most sites: 10 minutes after a cache-invalidating event, once every 5 minutes apart for each report type. On large sites: once a day at 4 am site time, 15 minutes apart for each report type.

Arguments:  The subscription-related report which needs updating.

Scaling Action Scheduler with WP-CLI ↑ Back to top

Action Scheduler has WP-CLI commands that can be used for processing actions. This can be particularly useful for large sites with long-running tasks, large queues, or many demands on WP-Cron. More information about using these commands can be found on the Action Scheduler site in the section about WP-CLI.

WooCommerce - the most customizable eCommerce platform for building your online business.

Back to the top