WooCommerce: Bulk Delete Pending / Failed Scheduled Actions

In a recent project, I needed a quick way to bulk delete pending and failed Action Scheduler jobs directly from the WordPress dashboard—so I built a custom tool for it.

The WooCommerce > Status > Tools section is packed with useful features for debugging and maintenance, but did you know you can add your own custom tools there?

This is especially useful when your site has thousands of queued actions that are no longer needed, or if a plugin malfunction leaves behind a large number of stuck jobs. Instead of running manual SQL queries or using WP CLI, this approach gives you a simple one-click button inside your WooCommerce admin.

In this tutorial, I’ll show you how to register your own custom tool using WooCommerce’s built-in API, and how to trigger and delete all pending or failed actions.

Here’s the full snippet to get you started!

Here are some custom tools added to the WooCommerce > Status > Tools section, ready to delete pending and failed scheduled actions.

PHP Snippet: Add Custom “Tool” To Delete Action Scheduler Failed / Pending Jobs @ WooCommerce Status

This PHP snippet adds a custom tool to the WooCommerce > Status > Tools section, allowing you to bulk delete all pending Action Scheduler actions directly from the WordPress dashboard.

It registers a new tool labeled “Clean Pending Actions” using the woocommerce_debug_tools filter. When the “Run” button is clicked, the callback runs a direct SQL query that deletes up to 10,000 rows per batch where the status is 'pending', repeating until no such actions remain.

This is particularly helpful if your database contains thousands of stuck or obsolete scheduled actions, which can slow down your site or clog the Action Scheduler queue.

If you’d rather delete failed actions instead, simply change 'pending' to 'failed' in the SQL WHERE clause. Be sure to also update the tool’s name and description accordingly so the admin interface reflects the correct behavior.

Use this with caution, especially on live sites, as it permanently deletes database entries!

/**
 * @snippet       Bulk Delete Action Scheduler Jobs
 * @tutorial      https://businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @compatible    WooCommerce 9
 * @community     https://businessbloomer.com/club/
 */

add_filter( 'woocommerce_debug_tools', 'bbloomer_bulk_delete_pending_scheduled_actions' );

function bbloomer_bulk_delete_pending_scheduled_actions( $tools ) {    
    $tools['clean_pending_actions'] = [
        'name' => 'Clean Pending Actions',
        'button' => 'Run',
        'desc' => 'Deletes all pending Action Scheduler actions.',
        'callback' => function() {
            global $wpdb;
            $table = $wpdb->prefix . 'actionscheduler_actions';
			   $batch_size = 10000;
            $deleted = 0;
            do {
                $rows_deleted = $wpdb->query( "DELETE FROM $table WHERE status = 'pending' LIMIT $batch_size" );
                $deleted += $rows_deleted;
            } while ( $rows_deleted > 0 );
            return sprintf( 'Deleted %d pending actions.', $deleted );
        }
    ];	
    return $tools;
}

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

2 thoughts on “WooCommerce: Bulk Delete Pending / Failed Scheduled Actions

  1. Hi Rodolfo,

    i hope you don’t mind me posting this snippet. I’ve put together an enhanced version that adds support for pending, failed, and completed statuses.

    add_filter( 'woocommerce_debug_tools', 'bbloomer_bulk_delete_all_statuses' );
    function bbloomer_bulk_delete_all_statuses( $tools ) {
        $statuses = [
            'pending'   => 'Clean Pending Actions',
            'failed'    => 'Clean Failed Actions',
            'complete'  => 'Clean Completed Actions',
        ];
    
        foreach ( $statuses as $status_key => $tool_name ) {
            $tools[ "clean_{$status_key}_actions" ] = [
                'name'     => $tool_name,
                'button'   => 'Run',
                'desc'     => sprintf( 'Deletes all <strong>%s</strong> Action Scheduler actions.', $status_key ),
                'callback' => function() use ( $status_key ) {
                    global $wpdb;
                    $table      = $wpdb->prefix . 'actionscheduler_actions';
                    $batch_size = 10000;
                    $deleted    = 0;
                    do {
                       $rows = $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE status = %s LIMIT %d", $status_key, $batch_size ) );
                       $deleted += $rows_deleted;
                       } while ( $rows_deleted > 0 );
                    return sprintf( 'Deleted %d %s actions.', $deleted, $status_key );
                },
            ];
        }
    
        return $tools;
    }
    

    Best regards,
    Borko

    1. I don’t mind at all! Thank you

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *