Skip to content
Development
Skill

/wp-background-processing

Use when a WordPress plugin needs to run work outside the HTTP request cycle — scheduling async or recurring jobs with Action Scheduler (as_enqueue_async_action, as_schedule_single_action, as_schedule_recurring_action, as_unschedule_action), implementing WP_Background_Process

From plugin
wp-dev-skills
2819 skills1 command

Claude Code

$ npx -y skills add mralaminahamed/wp-dev-skills --skill wp-background-processing --agent claude-code

SKILL.md

wp-background-processing.SKILL.md
name: wp-background-processing
description: "Use when a WordPress plugin needs to run work outside the HTTP request cycle — scheduling async or recurring jobs with Action Scheduler (as_enqueue_async_action, as_schedule_single_action, as_schedule_recurring_action, as_unschedule_action), implementing WP_Background_Process (push_to_queue, save, dispatch, is_queue_empty), registering WP Cron events (wp_schedule_event, wp_clear_scheduled_hook), batch-processing large datasets without hitting PHP timeouts, tracking job progress, handling retries on failure, or debugging the actionscheduler_actions table. Triggers: \"schedule this for later\", \"run this without hitting timeout\", \"queue these items for background processing\", \"why is my cron not running\", \"Action Scheduler job keeps failing\", \"as_enqueue_async_action\", \"WP_Background_Process\", \"push_to_queue\", \"dispatch the queue\", \"DISABLE_WP_CRON\", \"process records in batches\", \"send emails in the background\", \"WP Cron not firing\", \"batch import without timeout\", \"scheduled action not running\", \"background job stuck\", \"wp action-scheduler list\", \"recurring cron event\", \"progress tracking for batch job\", \"retry failed background tasks\", \"chunked processing to avoid timeout\", \"scheduled action completes but nothing happens\", \"my hook never fires in cron\", \"handler registered behind is_admin\", \"job runs in admin but not from cron\", \"webhook fired twice\", \"background job double-processed\", \"make my background job idempotent\". Not for: real-time AJAX handlers or synchronous REST endpoints."

WordPress Background Processing

> **Model note:** Scaffolding a new Action Scheduler or `WP_Background_Process` implementation is pattern-matching — `haiku` handles it well. Debugging a stuck queue or race condition across async jobs requires reasoning; use `sonnet`.

Implement background jobs and queued tasks in WordPress plugins. Three primary tools with distinct trade-offs: Action Scheduler (persistent, battle-tested), `WP_Background_Process` (lightweight, no DB table), WP Cron (built-in, unreliable timing).

When to use

  • "Process a large batch of items in the background", "queue a long-running task".
  • "Set up Action Scheduler", "use WooCommerce queue".
  • "Implement WP_Background_Process", "chunked batch import".
  • "Background email sending", "async API calls".
  • "Fix a WP Cron job not firing", "make scheduled tasks reliable".
  • "The scheduled action completes but nothing happens", "the handler only runs in the admin".

**Not for:** One-off scheduled events (use `wp_schedule_single_event`). REST API async patterns — use `wp-rest-api`.

Method

1. Choose the right tool

| Tool | Persistent | Retry | Progress | Requires | Best for | |---|---|---|---|---|---| | Action Scheduler | ✅ DB table | ✅ Configurable | Via hooks | AS or WC | Reliable multi-step queues | | WP_Background_Process | ✅ Options API | ❌ Manual | Via option | ~5KB class | Simple batches, no WC dep | | WP Cron | ❌ (transient) | ❌ | ❌ | Nothing | Maintenance, low-priority tasks |

**Rule of thumb:** WooCommerce already installed → Action Scheduler. Simple background batch → `WP_Background_Process`. Periodic cleanup task → WP Cron.

2. Action Scheduler

Bundled with WooCommerce. Can also be installed as a standalone library.

**Standalone install:**

composer require woocommerce/action-scheduler
require_once plugin_dir_path( __FILE__ ) . 'vendor/woocommerce/action-scheduler/action-scheduler.php';

**Schedule and handle actions:**

// Schedule a single action (fires once ASAP)
as_enqueue_async_action( 'my_plugin_process_item', [ 'item_id' => 123 ], 'my-plugin' );

// Schedule a recurring action
as_schedule_recurring_action( time(), HOUR_IN_SECONDS, 'my_plugin_hourly_sync', [], 'my-plugin' );

// Schedule a single action in the future
as_schedule_single_action( time() + 300, 'my_plugin_delayed_job', [ 'batch' => 1 ], 'my-plugin' );

// Handle the action
add_action( 'my_plugin_process_item', function( $item_id ) {
    $result = my_plugin_do_work( $item_id );
    if ( is_wp_error( $result ) ) {
        // AS will retry on exception; throw to trigger retry
        throw new \Exception( $result->get_error_message() );
    }
} );

**Batch queue (fan-out pattern):**

function my_plugin_queue_all_items() {
    $items = get_posts( [ 'post_type' => 'my_type', 'posts_per_page' => -1, 'fields' => 'ids' ] );
    foreach ( $items as $id ) {
        // Skip if already scheduled
        if ( ! as_has_scheduled_action( 'my_plugin_process_item', [ 'item_id' => $id ], 'my-plugin' ) ) {
            as_enqueue_async_action( 'my_plugin_process_item', [ 'item_id' => $id ], 'my-plugin' );
        }
    }
}

**Cancel scheduled actions:**

as_unschedule_action( 'my_plugin_hourly_sync', [], 'my-plugin' );
as_unschedule_all_actions( 'my_plugin_process_item', [], 'my-plugin' );

**Monitor via WP-CLI:**

wp action-scheduler list --group=my-plugin --status=pending
wp action-scheduler run --group=my-plugin

3. WP_Background_Process

Lightweight 2-class library using WP options + transients for queue state. No extra DB table.

composer require deliciousbrains/wp-background-processing

**Extend the class:**

class My_Plugin_Batch_Process extends WP_Background_Process {

    protected $action = 'my_plugin_batch'; // Unique key — used for cron and option names

    protected function task( $item ) {
        // Process one item. Return false to remove from queue; return $item to re-queue.
        $result = my_plugin_process( $item['id'] );
        if ( is_wp_error( $result ) ) {
            // Log and skip — returning $item would re-queue endlessly
            error_log( 'my-plugin: failed item ' . $item['id'] . ': ' . $result->get_error_message() );
            return false;
        }
        return false; // Done — remove from queue
    }

    protected function complet
Read more
@mralaminahamed
Ships withwp-dev-skills

Covers the complete WordPress plugin development lifecycle — build, test, audit, release, and ship to WP.org — for Claude Code, Gemini CLI, Cursor, Windsurf, Cline, Codex, GitHub Copilot, opencode, and more.

Stars on GitHub

Momentum

stars in total
28
Star history of mralaminahamed/wp-dev-skills on GitHub, a chart by star-history.com

Other skills on wp-dev-skills.

wp-ci-qa

wp-ci-qa

Use when a pull request has QA failures, a \"Testing Failed\" label, or QA comments reporting broken features — reading QA…

wp-database

wp-database

Use when a WordPress plugin needs a custom database table — creating with dbDelta (strict SQL format: two spaces before PRIMARY…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about wp-background-processing.

Which coding agents can use wp-background-processing?
wp-background-processing installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.