PHPackages                             apinstein/jqjobs - 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. apinstein/jqjobs

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

apinstein/jqjobs
================

Async job manager for PHP.

v1.2.8(8y ago)3220.2k5[11 issues](https://github.com/apinstein/jqjobs/issues)[2 PRs](https://github.com/apinstein/jqjobs/pulls)MITPHPPHP &gt;=5.2.0

Since Jan 17Pushed 8y ago5 watchersCompare

[ Source](https://github.com/apinstein/jqjobs)[ Packagist](https://packagist.org/packages/apinstein/jqjobs)[ Docs](http://github.com/apinstein/jqjobs)[ RSS](/packages/apinstein-jqjobs/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (3)Versions (28)Used By (0)

JQJobs is a job queue infrastructure for PHP.

Features

- Very light-weight and easy-to-use.
- Supports multiple job types.
- Supports multiple queues &amp; binding workers to specific queues.
- Supports jobs that proxy the work to third-party services. This allows other jobs to be worked on but tracks the status of the third-party job through JQJobs.
- Tracks job enqueue time, start time, and finish time.
- Priority scheduling.
- Coalescing job support (if a job with the same coalesceId is enqueued, no duplicate job is created; the original is returned). This is basically a lightweight built-in mutex to help you prevent from creating duplicate jobs for the same "thing".
- Tested in highly-concurrent production environment with over 3M jobs processed over 2+ years.
- Queue store is architecturally independent of JQJobs; use our JQStore\_Array or JQStore\_Propel (db) or write your own.
- Workers automatically pre-flight memory availability and gracefully restart in low-memory situations to avoid OOM's during job processing.
- Workers automatically check all source code files in use and gracefully restart if any underlying code has been modified.
- Workers can have their priority adjusted (ideal for background tasks on web servers for instance).
- Logs failed job messages.
- Workers designed to be run under runit or similar process supervisor for maintenance-free operation.
- Auto-retry failed jobs.
- Good test coverage.
- Utility class JQDelayedJob makes it trivial to run php code after the script exits. This is a great way to defer things like logging to after the request is handled for a more performant application.
- Optional jitter for high-concurrency situations
- Robust signal handling, including graceful shutdown on SIGTERM
- Robust autoscaler with Heroku and AWS (Auto-scaling groups) drivers.
- Hung jobs detection (will be re-queued).
- Built-in support for ASYNC jobs (jobs where work is sent "offsite" and will be closed out asyncronously via JQManagedJob::STATUS\_WAIT\_ASYNC and JQManagedJob::resolveWaitAsyncJob().

Roadmap

- Queue admin tool (cli &amp; gui)

The job system has only a few core parts:

- JQJob is an interface for a class that does actual work.
- JQManagedJob is a wrapper for JQJob's which contains metadata used to manage the job (status, priority, etc).
- JQStore is where JQManagedJob's are persisted. The application queues jobs in a JQStore for later processing.
- JQWorker runs jobs from the queue. It is typically run in a background process.

Additional Utilities:

- JQAutoscaler is a utility that can manage auto-scaling your worker pool.
- JQDelayedJob is a utility class for registering a function or job to be run after the script exits.

The JQStore manages the queue and persistence of the JQManagedJob's.

JQStore is an interface, but the job system ships with several concrete implementations. The system is architected in this manner to allow the job store to be migrated to different backing stores (memcache, db, Amazon SQS, etc). JQStore implementations are very simple.

Jobs that complete successfully are removed from the queue immediately. Jobs that fail are retried until maxAttempts is reached, and then they are marked FAILED and left in the queue. It's up to the application to cleanup failed entries.

If the application requires an audit log or archive of job history, it should implement this in run()/cleanup() for each job, or in a custom JQStore subclass.

The minimal amount of work needed to use a JQJobs is 1) create at least one job; 2) create a queuestore; 3) add jobs; 4) start a worker.

1. Create a job

    class SampleJob implements JQJob { function \_\_construct($info) { $this-&gt;info = $info; } function run() { print $this-&gt;description() . "\\n"; } // no-op function cleanup() { print "cleanup() {$this-&gt;description()}\\n"; } function statusDidChange(JQManagedJob $mJob, $oldStatus, $message) { print "SampleJob \[Job {$mJob-&gt;getJobId()}\] {$oldStatus} ==&gt; {$mJob-&gt;getStatus()} {$message}\\n"; } function description() { return "Sample job {$this-&gt;info}"; } }
2. Create a queuestore

    $q = new JQStore\_Array();

    // alternatively; create a db-based queue with Propel: $con = Propel::getConnection(JQStoreManagedJobPeer::DATABASE\_NAME); $q = new JQStore\_Propel('JQStoreManagedJob', $con);
3. Add jobs

    foreach (range(1,10) as $i) { $q-&gt;enqueue(new SampleJob($i)); }
4. Start a worker to run the jobs.

    declare(ticks = 1); // to have JQJobs be able to gracefully handle SIGKILL (or other *immediate termination* signals) // the declare(ticks=1) must be in global scope. $w = new JQWorker($q); $w-&gt;start();
5. If you want hung jobs detection and you aren't using JQAutoscaler, you will need to schedule a task to run JQStore::detectHungJobs().

=======================

JQDelayedJob Example

```
JQDelayedJob::doLater(new MyJob('data'));
JQDelayedJob::doLater(function() { print "Hello, World. I am running from a delayed job after the script exits!"; });

```

INSTALLATION

pear install apinstein.pearfarm.org/jqjobs

See

SOURCE

### JQStore Backends

[](#jqstore-backends)

Propel
------

[](#propel)

Currently the only db-backed JQStore implememtation is for Propel ORM. All migrations needed for JQJobs/Propel to function are in the migrations/ folder which is expected to be run with mp (github.com/apinstein/mp). This could easily be adapter into a Propel plugin, but hasn't yet.

In any case, just ensure that if you are installing/upgrading your JQJobs that you copy and re-sequence the migrations as needed.

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance13

Infrequent updates — may be unmaintained

Popularity32

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 72.6% 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 ~145 days

Recently: every ~166 days

Total

14

Last Release

2971d ago

### Community

Maintainers

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

---

Top Contributors

[![apinstein](https://avatars.githubusercontent.com/u/34889?v=4)](https://github.com/apinstein "apinstein (127 commits)")[![lorennorman](https://avatars.githubusercontent.com/u/17697?v=4)](https://github.com/lorennorman "lorennorman (40 commits)")[![woofyman99](https://avatars.githubusercontent.com/u/357084?v=4)](https://github.com/woofyman99 "woofyman99 (5 commits)")[![ardell](https://avatars.githubusercontent.com/u/90694?v=4)](https://github.com/ardell "ardell (2 commits)")[![jasonbouffard](https://avatars.githubusercontent.com/u/181576?v=4)](https://github.com/jasonbouffard "jasonbouffard (1 commits)")

---

Tags

queuejob

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/apinstein-jqjobs/health.svg)

```
[![Health](https://phpackages.com/badges/apinstein-jqjobs/health.svg)](https://phpackages.com/packages/apinstein-jqjobs)
```

###  Alternatives

[imtigger/laravel-job-status

Laravel Job Status

5272.1M3](/packages/imtigger-laravel-job-status)[jms/job-queue-bundle

Allows to run and schedule Symfony console commands as background jobs.

3462.3M5](/packages/jms-job-queue-bundle)[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

144691.7k4](/packages/clue-mq-react)[mpbarlow/laravel-queue-debouncer

A wrapper job for debouncing other queue jobs.

63714.4k1](/packages/mpbarlow-laravel-queue-debouncer)[mariano/disque-php

PHP library for Disque, an in-memory, distributed job queue

134118.5k2](/packages/mariano-disque-php)[tarantool/queue

PHP bindings for Tarantool Queue.

64136.2k4](/packages/tarantool-queue)

PHPackages © 2026

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