kamranata/queue-sql
A Laravel package that provides a SQL-backed queue driver, letting you store and process queued jobs directly in your database without relying on external queue services like Redis or SQS. Useful for simple deployments and small apps.
upsert() terminal makes the package a credible answer to "how do we get 100k+ rows into the database without blocking a request or writing our own chunker, retry logic, and batch tracker?" That is a build-vs-buy decision most teams under-cost: the naive version is a week of work plus a permanent tail of edge cases.uniqueBy column set let you promise "a retried or duplicated job cannot create duplicate rows." That directly supports features where duplicates are user-visible — view counters, daily rollups, usage metering, leaderboard stats — and lets you ship at-least-once queue semantics without a bespoke dedupe layer.queue-sql:status --json turns batch progress into a machine-readable feed, so the question shifts from "do we build custom progress tracking?" to "do we point Grafana/Datadog at this endpoint?" --watch is dev-ergonomics, not production surface (it deliberately degrades to a single render when piped), so don't plan monitoring around it.Adopt when most of these hold:
insert loops inside a request or a controller-less artisan command.upsert(uniqueBy: ...) is meaningful.INSERT/UPSERT over the existing connection is genuinely cheapest.Look elsewhere when:
upsert gives you idempotent effects on a unique key, which is not the same thing; be precise with stakeholders about the difference.COPY/LOAD DATA, or a dedicated loader, will dominate.Dependency risk to price in: this is a single-maintainer package. Mitigate by pinning the version, confining usage behind a thin internal interface (one class that owns the queue()->upsert()->dispatch() call), and keeping a fallback path to plain chunked upsert in a job. That containment cost is small and should be a stated condition of adoption, not a surprise later.
To executives: We can keep large data writes off the request path and out of our engineers' backlog without buying or building new infrastructure. The v1.4.0 release closes the failure mode that mattered most — a retried job duplicating rows — so the numbers we show in dashboards and usage reports stay correct even when the queue misbehaves. It also emits status as JSON, which means existing monitoring can watch these jobs without a custom integration. Cost is one small dependency on infrastructure we already run; the main risk is that it's maintained by a single author, which we contain by pinning the version and wrapping it behind our own interface.
To engineering: v1.4.0 adds an upsert() terminal that fans out over rows like insert, but each chunk is an idempotent upsert keyed on uniqueBy — retries no longer create duplicates. It respects chunk and maxJobs, and it propagates queue-sql:upsert:{table} batch names and Horizon tags so batches stay traceable in the tooling we already use. queue-sql:status --json gives us a machine-readable feed for dashboards; --watch is for local debugging and intentionally renders once when output isn't a TTY, so it isn't a production monitoring story. No breaking changes noted in this release. Recommended adoption pattern: one internal wrapper class owns every call site, so an upstream abandonment or a schema change costs us a single file to unwind.
How can I help you explore Laravel packages today?