Queuety

Getting Started

Installation

composer require queuety/queuety

Activate the plugin

wp plugin activate queuety

On activation, Queuety creates its database tables (queuety_jobs, queuety_workflows, queuety_logs, queuety_schedules, queuety_signals, queuety_chunks, queuety_queue_states, queuety_webhooks) and installs a bootstrap file that allows workers to run without booting WordPress.

Configuration

All constants are optional. Define them in wp-config.php before the plugin loads:

ConstantDefaultDescription
QUEUETY_RETENTION_DAYS7Auto-purge completed jobs after N days
QUEUETY_LOG_RETENTION_DAYS0Auto-purge logs after N days (0 = keep forever)
QUEUETY_MAX_EXECUTION_TIME300Max seconds per job before timeout
QUEUETY_WORKER_SLEEP1Seconds to sleep when queue is empty
QUEUETY_WORKER_MAX_JOBS1000Max jobs before worker restarts
QUEUETY_WORKER_MAX_MEMORY128Max MB before worker restarts
QUEUETY_RETRY_BACKOFFexponentialBackoff strategy: exponential, linear, or fixed
QUEUETY_STALE_TIMEOUT600Seconds before stuck jobs are recovered
QUEUETY_CACHE_TTL5Default cache TTL in seconds
QUEUETY_DEBUGfalseEnable verbose worker logging
QUEUETY_TABLE_JOBSqueuety_jobsJobs table name
QUEUETY_TABLE_WORKFLOWSqueuety_workflowsWorkflows table name
QUEUETY_TABLE_LOGSqueuety_logsLogs table name
QUEUETY_TABLE_SCHEDULESqueuety_schedulesSchedules table name
QUEUETY_TABLE_SIGNALSqueuety_signalsSignals table name
QUEUETY_TABLE_CHUNKSqueuety_chunksStreaming chunks table name
QUEUETY_TABLE_QUEUE_STATESqueuety_queue_statesQueue states table name
QUEUETY_TABLE_WEBHOOKSqueuety_webhooksWebhooks table name

Your first job

Create a handler class that implements the Handler interface:

use Queuety\Handler;

class SendEmailHandler implements Handler {
    public function handle( array $payload ): void {
        wp_mail( $payload['to'], $payload['subject'], $payload['body'] );
    }

    public function config(): array {
        return [
            'queue'           => 'emails',
            'max_attempts'    => 5,
            'needs_wordpress' => true,
        ];
    }
}

Register it and dispatch:

use Queuety\Queuety;

Queuety::register( 'send_email', SendEmailHandler::class );

Queuety::dispatch( 'send_email', [
    'to'      => 'user@example.com',
    'subject' => 'Welcome',
    'body'    => 'Hello from Queuety!',
] );

Or use the modern dispatchable job class:

use Queuety\Contracts\Job;
use Queuety\Dispatchable;

readonly class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

SendEmailJob::dispatch( 'user@example.com', 'Welcome', 'Hello from Queuety!' );

Your first workflow

Define step handlers that implement the Step interface:

use Queuety\Step;

class FetchDataHandler implements Step {
    public function handle( array $state ): array {
        $user = get_user_by( 'ID', $state['user_id'] );
        return [ 'user_name' => $user->display_name ];
    }

    public function config(): array {
        return [ 'needs_wordpress' => true ];
    }
}

class CallLLMHandler implements Step {
    public function handle( array $state ): array {
        $response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', [
            'body' => json_encode( [ 'prompt' => "Generate report for {$state['user_name']}" ] ),
        ] );
        return [ 'llm_response' => wp_remote_retrieve_body( $response ) ];
    }

    public function config(): array {
        return [ 'needs_wordpress' => true, 'max_attempts' => 5 ];
    }
}

class FormatOutputHandler implements Step {
    public function handle( array $state ): array {
        $url = save_report( $state['user_name'], $state['llm_response'] );
        return [ 'report_url' => $url ];
    }

    public function config(): array {
        return [ 'needs_wordpress' => true ];
    }
}

Dispatch the workflow:

$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );

Start a worker

wp queuety work

The worker polls for pending jobs, executes them, advances workflows, and sleeps when the queue is empty. Press Ctrl+C to stop.

For production, run multiple workers:

wp queuety work --workers=4

Process multiple queues with priority ordering:

wp queuety work --queue=high,default,low

What's next

  • Jobs for the complete dispatch and handler guide
  • Workflows for chains, parallel steps, conditional branching, and sub-workflows
  • Middleware for rate limiting, throttling, and custom pipeline logic
  • Batching for dispatching groups of jobs with callbacks
  • Streaming Steps for persisting streamed data chunk by chunk
  • Scheduling for recurring jobs
  • Caching for the pluggable cache layer
  • Testing for QueueFake and test assertions
  • CLI Reference for all available commands
  • PHP API for programmatic access

On this page