PHPackages                             wptechnix/wp-background-jobs - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. wptechnix/wp-background-jobs

ActiveLibrary[Queues &amp; Workers](/categories/queues)

wptechnix/wp-background-jobs
============================

A simple, reliable, zero-dependency background job queue for WordPress. Object jobs, delays, retries with backoff, failed-jobs table, atomic reservation, async and WP-Cron and WP-CLI processing.

v2.0.0(1mo ago)06MITPHPPHP ^8.0CI passing

Since Jul 13Pushed 1mo agoCompare

[ Source](https://github.com/WPTechnix/wp-background-jobs)[ Packagist](https://packagist.org/packages/wptechnix/wp-background-jobs)[ RSS](/packages/wptechnix-wp-background-jobs/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (14)Versions (4)Used By (0)

WP Background Jobs
==================

[](#wp-background-jobs)

[![Latest Version](https://camo.githubusercontent.com/c5d4983000a710520aa77e1f1d6c2d5dd1ca8484c79a34997b3f11f85117d7ec/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7770746563686e69782f77702d6261636b67726f756e642d6a6f62732e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/wptechnix/wp-background-jobs)[![License](https://camo.githubusercontent.com/f13c4b381756945d549dfcd69fa7a8d657a8b44ff596e9958ed1f2acb76b5361/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7770746563686e69782f77702d6261636b67726f756e642d6a6f62732e7376673f7374796c653d666f722d7468652d6261646765)](LICENSE)[![PHP Version Require](https://camo.githubusercontent.com/a4683d793e35b1ee84a86944430e0ab4fda6de671f1eb0456fd0b8052311cd81/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f7770746563686e69782f77702d6261636b67726f756e642d6a6f62732f7068702e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/wptechnix/wp-background-jobs)

A simple, reliable background job queue for WordPress plugins. Define a job, dispatch it, and let it run outside the current request. It has zero runtime dependencies, its own indexed database tables, atomic job reservation that is safe under concurrency, and automatic retries with backoff.

It is built for plugins that need background work without pulling in a heavy queue stack, and it scales from a small site running on WP-Cron to a large one draining the queue with WP-CLI.

Key Features
------------

[](#key-features)

- 🧱 **Object jobs** - extend one class, implement `handle()`, dispatch it.
- 🗂️ **Dedicated, indexed tables** - no `wp_options` bloat, no `LIKE` scans.
- 🔒 **Atomic reservation** - a compare-and-swap claim prevents double processing on every MySQL and MariaDB version, with no `SKIP LOCKED` requirement.
- 🔁 **Retries with backoff** - configurable per job, with a failed-jobs table you can retry, list, or clear from PHP or WP-CLI.
- ⏱️ **Delayed and named queues** - schedule work for later and route it to named queues.
- 🚀 **Three ways to run** - an instant async kick, a WP-Cron watchdog safety net, and a WP-CLI worker for scale.
- 🧩 **No runtime dependencies** - observability comes from action hooks, so nothing can conflict with the host environment.
- 🛡️ **Job class allowlist** - restrict which classes can be unserialized for defense-in-depth against payload injection.
- 🛡️ **Conflict-free by design** - table names and hook names are derived from a per-plugin key, so two plugins never collide.
- 🌐 **Multisite ready** - all state is per-blog (tables, options, lock, cron), so every site runs an independent queue. See [Getting Started](docs/01-Getting-Started.md#multisite).

Installation
------------

[](#installation)

**Requirements:** PHP 8.0+, WordPress 5.0+, Composer.

```
composer require wptechnix/wp-background-jobs
```

Quick Start
-----------

[](#quick-start)

### 1. Create the manager and install its tables

[](#1-create-the-manager-and-install-its-tables)

```
use WPTechnix\WP_Background_Jobs\Background_Jobs;

function myplugin_jobs(): Background_Jobs {
    global $wpdb;
    static $jobs = null;
    if ( null === $jobs ) {
        $jobs = Background_Jobs::create( $wpdb, 'myplugin_tasks' );
    }
    return $jobs;
}

// Create the tables on activation.
register_activation_hook( __FILE__, static function () {
    myplugin_jobs()->install();
} );

// Register hooks, the cron watchdog, and CLI commands on every request.
add_action( 'plugins_loaded', static function () {
    myplugin_jobs()->boot();
} );
```

### 2. Define a job

[](#2-define-a-job)

```
use WPTechnix\WP_Background_Jobs\Job;

final class Send_Welcome_Email extends Job {

    public function __construct( private int $user_id ) {}

    public function handle(): void {
        $user = get_userdata( $this->user_id );
        if ( false !== $user ) {
            wp_mail( $user->user_email, 'Welcome', 'Thanks for joining.' );
        }
    }
}
```

### 3. Dispatch it

[](#3-dispatch-it)

```
// Run as soon as possible, in the background.
myplugin_jobs()->dispatch( new Send_Welcome_Email( 42 ) );

// Run in five minutes.
myplugin_jobs()->dispatch( new Send_Welcome_Email( 42 ), delay: 300 );

// Route to a named queue.
myplugin_jobs()->on( 'emails' )->dispatch( new Send_Welcome_Email( 42 ) );

// Queue many jobs in a single insert.
myplugin_jobs()->dispatch_many( [
    new Send_Welcome_Email( 42 ),
    new Send_Welcome_Email( 43 ),
] );
```

That is the whole loop: dispatch adds a row and fires one non-blocking request that starts a worker in a separate process. If that request cannot run on your host, the WP-Cron watchdog picks the work up within a minute instead.

How Processing Works
--------------------

[](#how-processing-works)

Every dispatch inserts a row and, once per request, fires a single non-blocking loopback request to `admin-ajax.php` that starts a worker. The worker drains jobs until the queue is empty or it reaches its time or memory budget, then it hands off to a fresh process so work spans many short requests safely.

A WP-Cron event runs on a schedule as an always-on safety net, so the queue still drains on hosts where loopback requests are blocked. For large backlogs, a long running WP-CLI worker is available. See [How Processing Works](docs/04-How-Processing-Works.md) for the details.

Full Documentation
------------------

[](#full-documentation)

- [Getting Started](docs/01-Getting-Started.md)
- [Defining Jobs](docs/02-Defining-Jobs.md)
- [Dispatching Jobs](docs/03-Dispatching-Jobs.md)
- [How Processing Works](docs/04-How-Processing-Works.md)
- [Retries and Failures](docs/05-Retries-and-Failures.md)
- [WP-CLI](docs/06-WP-CLI.md)
- [Configuration and Hooks](docs/07-Configuration-and-Hooks.md)

Development
-----------

[](#development)

The toolchain runs entirely in Docker, so no local PHP or Composer is required.

### Using Docker Compose

[](#using-docker-compose)

```
docker compose run --rm php composer install
docker compose run --rm php bash
```

### Running the checks

[](#running-the-checks)

```
docker compose run --rm php composer test     # PHPUnit
docker compose run --rm php composer lint      # PHPCS + PHPStan
docker compose run --rm php composer phpcbf    # Auto-fix coding standards
```

License
-------

[](#license)

MIT. See [LICENSE](LICENSE).

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance93

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~6 days

Total

3

Last Release

36d ago

Major Versions

v1.0.1 → v2.0.02026-07-26

### Community

Maintainers

![](https://www.gravatar.com/avatar/e0fb168547a02b4a7b28df9403ab375f354591c75e814dce020f245e77f04e5f?d=identicon)[owaisahmed5300](/maintainers/owaisahmed5300)

---

Top Contributors

[![owaisahmed5300](https://avatars.githubusercontent.com/u/28684548?v=4)](https://github.com/owaisahmed5300 "owaisahmed5300 (12 commits)")

---

Tags

asyncbackground-jobsbackground-processingjobs-queuequeuetask-queuewordpressworkerwp-cliwp-cronasyncwordpressqueueworkerwp-clibackground-jobstask-queuewp-cronjob queuebackground processing

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/wptechnix-wp-background-jobs/health.svg)

```
[![Health](https://phpackages.com/badges/wptechnix-wp-background-jobs/health.svg)](https://phpackages.com/packages/wptechnix-wp-background-jobs)
```

###  Alternatives

[clue/mq-react

Mini Queue, the lightweight in-memory message queue to concurrently do many (but not too many) things at once, built on top of ReactPHP

145862.1k4](/packages/clue-mq-react)[tochka-developers/queue-promises

Promises for Laravel queue jobs

1912.3k](/packages/tochka-developers-queue-promises)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
