Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Jobqueuebundle Laravel Package

tomatom/jobqueuebundle

A Symfony bundle for running background jobs through a simple queue. Dispatch jobs from your application, process them asynchronously with workers, and keep long-running tasks out of web requests. Useful for deferring emails, exports, and other time-consuming work.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalize: this is not a Laravel package. It is a Symfony 6+ bundle (TomAtomCZ/JobQueueBundle), a re-implementation of JMSJobQueueBundle with a browser UI. There is no service provider, no config/jobqueue.php, no php artisan commands, and no Laravel queue driver. If you composer require it into a Laravel app you will get a bundle class and Doctrine entities that Laravel never boots.

So "getting started" means deciding where it runs:

  1. Sidecar service (recommended). Stand up a small Symfony 6/7 app whose only job is running this bundle. Your Laravel app enqueues work by calling an HTTP endpoint on the sidecar (or pushing to a shared Redis/SQS queue the sidecar consumes). The sidecar owns the job tables and the browser UI; Laravel stays on Horizon/queue:work.
  2. Shared database. Both apps point at the same MySQL/Postgres schema. The Symfony side owns the job tables via Doctrine migrations; Laravel only reads/writes rows through a thin repository or, better, through the sidecar's API.
  3. Don't use it. If your only requirement is "background jobs with a dashboard," Laravel Horizon + Telescope already covers it. Adopt this bundle only if you specifically want its entity-centric job history and UI.

If you are actually working inside Symfony (the intended audience), the sequence is: composer require, register the bundle in config/bundles.php, point it at a Doctrine connection, run the bundle's migrations, then hit the browser route. Check the README for the exact bundle class name, route prefix, and worker command — treat those as authoritative, not memory.

First use case: a long-running "generate report / import CSV" job attached to a domain record, where an operator needs to see per-record job history and retry failures from a web page. That is the bundle's sweet spot and the thing Horizon does not give you out of the box.

Implementation Patterns

Sidecar dispatch. From Laravel, keep the hand-off dumb and idempotent:

Http::withToken(config('services.jobqueue.token'))
    ->post(config('services.jobqueue.url').'/api/jobs', [
        'type' => 'report.export',
        'payload' => $payload,
        'related' => ['type' => 'invoice', 'id' => $invoice->id],
        'idempotency_key' => "report:{$invoice->id}:{$month}",
    ]);

Return the sidecar's job id and store it on your Eloquent model (jobqueue_ref) so you can correlate back.

Mirror the entity-centric model in Eloquent. The bundle's key idea is a Job linked to a related entity (JobRelatedEntity in the JMS lineage). If you stay in Laravel, replicate that shape with a polymorphic relation rather than one flat jobs table:

// jobs: id, type, status, payload, jobable_type, jobable_id, started_at, finished_at, output
$invoice->jobs()->latest()->first()?->status;

This is what makes the UI useful — operators click a record and see its job timeline.

Supervisor, not artisan. The worker is a bin/console long-running process, typically something like bin/console <bundle>:run (confirm the name). Manage it with Supervisor/systemd, exactly as you'd manage queue:work — autorestart=true, stopwaitsecs, one process per queue.

Treat the browser UI as an ops dashboard. It has its own routing and, likely, no authentication of its own. Put it behind a reverse proxy with basic auth, or an IP allowlist / VPN, and never expose it to the internet. Do not try to bolt Laravel's auth middleware onto it — different framework, different session stack.

Bridging events. Have the sidecar emit a webhook or write to a shared job_events table that Laravel polls (or a Redis pub/sub channel it subscribes to) so your app can react to job completion without querying the Doctrine DB directly.

Concept mapping if you're porting from Laravel:

Laravel This bundle
php artisan queue:work Bundle's console worker command
app/Jobs/* Doctrine job entities / handlers registered as services
failed_jobs table Job status + retry in the browser UI
Horizon dashboard Browser interface (unauthenticated by default)
Queue::push() Persisting a job entity / service call

Gotchas and Tips

  • GPL-2.0 is a real constraint. This is copyleft, not MIT. Running it as a separate sidecar process reduces the "derivative work" argument, but linking the bundle into a distributed product almost certainly triggers source-disclosure obligations. Get legal sign-off before shipping anything closed-source. This alone may disqualify it for many Laravel SaaS teams.
  • Six stars, zero dependents, last release dated 2026. Treat it as effectively unmaintained. Vendor/fork it, pin the exact commit, and own the upgrade path. Don't expect Symfony 8 or PHP 9 support.
  • Dual-ORM dual-write hazard. If both apps touch the same tables, Doctrine's unit-of-work and Eloquent's dirty tracking will fight you: stale reads, lost updates, timestamp columns in the wrong format. Pick one writer — the sidecar — and have Laravel talk to it over HTTP.
  • Migrations are owned by the Symfony side. Never let Laravel's php artisan migrate create or alter the bundle's tables. Keep the bundle's Doctrine migrations in its own migration namespace and run them from the sidecar deploy.
  • No Laravel auth, CSRF, or middleware on the UI. As above: proxy-level protection. Also check whether the UI exposes raw job payloads/output — that's a data-leak surface.
  • Long-running worker memory. Doctrine's entity manager accumulates objects. If the bundle doesn't reset it per iteration, schedule supervisor restarts (e.g. --max-jobs-style flag, or a restart every N jobs). Watch RSS in staging.
  • Code-version skew. The worker must run the same code version as the dispatcher that created the job. With a sidecar this means deploying the sidecar in lockstep, or versioning job type strings and keeping old handlers around.
  • Config lives in YAML, not PHP. Bundle config is config/packages/*.yaml with env-var interpolation (%env(...)%). If you're used to config/*.php + env(), this is a mental shift — and cached config (cache:clear) will bite you when env vars change.
  • Debugging failures. Start with the worker's stdout/stderr (Supervisor log), not Laravel's storage/logs/laravel.log. The browser UI's job detail page is usually the fastest way to see the exception and retry.
  • Extension points to lean on: register custom job types/handlers as tagged Symfony services; override the bundle's Twig templates to add your branding/links; hook the job lifecycle events if exposed, to push status back to Laravel.
  • The honest recommendation: for a Laravel team, this is at best a niche sidecar for entity-centric job history with an operator UI. Compare it against Horizon's tags/monitoring and a tiny custom job_runs table first — you can usually get 90% of the value in an afternoon without a second framework, a second ORM, and a GPL license.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource