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

Laravel Queue Batch Retry Laravel Package

kirschbaum-development/laravel-queue-batch-retry

Retry failed jobs in Laravel queue batches with a simple artisan command. This package re-dispatches failed batch jobs while preserving batch context, so you can recover from failures without manually tracking or re-queuing individual jobs.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Turning "batch failure" from a scramble into a runbook step. Batched work is where customer-visible promises live: bulk imports and exports, invoice/report generation, notification and email fan-outs, media pipelines, CRM/ERP syncs, per-tenant provisioning. Today a partial failure means either re-running the whole batch (duplicative, customer-visible, expensive) or hand-picking failed job UUIDs from failed_jobs. This package makes "retry only the failed jobs, minus the ones we know are broken" a repeatable operation — the prerequisite for committing to any recovery expectation at all.

  • Build vs. buy: buy, with a deliberately cheap exit. The alternative is a homegrown Artisan command over job_batches / failed_jobs — cheap to write once, expensive to own. It drifts from Laravel internals, accretes one-off filters, and lives in one engineer's head. This package covers the same ground for one Composer line and can be swapped for a short internal script if abandoned. That asymmetry makes adoption the default rather than a debate worth scheduling.

  • Roadmap: surgical recovery is now a real option, so scope can grow. The --exclude-filter flag added in 1.2.2 is the strategically interesting change. The prior choice was binary — replay the entire batch, or name individual jobs. Scoped operations like retry everything in the Billing namespace except the Stripe integration we know is down are now expressible. Any roadmap item currently assuming "batch failure = full re-run" should be re-estimated; removing duplicate side effects from the critical path is a product-quality gain, not just an ops convenience.

  • Blast-radius control becomes a product lever. Retrying is a write against production queue state. Over-broad selection floods workers and duplicates customer-visible effects; over-broad exclusion silently skips the one job that needed to run. Filtering is the difference between a 5-job retry and a 5,000-job duplicate send — and since that is a command-syntax decision, it belongs in a documented runbook, not in tribal knowledge.

  • Keeps us on native Laravel batching. This supports the standing decision not to migrate to a durable-execution platform for this class of work. It is operational tooling, not platform: no schema changes, no vendor contract, no new product surface, off the deploy path.

Use cases: bulk CRM/ERP syncs, data imports and exports, large notification fan-outs, bulk invoice/report generation, media processing, per-tenant provisioning. The common shape is a long-running batch of mostly independent jobs where a minority fail transiently.

When to Consider This Package

Consider it when:

  • The app already uses Bus::batch() and the native job_batches / failed_jobs tables. Without native batching there is nothing to act on — this is table stakes.
  • Operators regularly retry failed jobs today, and the current method is a runbook of copied UUIDs or a bespoke script.
  • You need selective retry: narrow to a job class or namespace (--filter) and carve out a known-bad dependency (--exclude-filter). That is the gap between Laravel core's whole-batch queue:retry-batch and what incidents actually demand. If you don't need filters, prefer core and take the smaller risk.
  • Duplicate side effects and on-call minutes are measurable costs. If a partial failure currently means re-running thousands of jobs and manually de-duplicating downstream data, the ROI case is immediate.
  • You want a small, Laravel-native utility with no migrations, no config, minimal surface area. Pin at ^1.2 so the exclusion flag isn't silently missing on a stale ops box still on 1.2.1.

Look elsewhere — or stay manual — when:

  • The failure model needs dependency graphs, cross-queue orchestration, sagas/compensation, or durable execution. That is a workflow engine (Temporal, Laravel Workflow), not a retry command.
  • You need audit trails, approval gates, RBAC on retry actions, or SOC 2-grade change control. None of that is here and it won't grow it.
  • The workflow is customer-facing and high-stakes enough to require vendor support or an SLA. 51 stars, zero dependents, single maintainer, last release 2024-06-11 — real, but not vendor-backed.
  • Horizon is already the team's retry interface. Adding a second path to the same mutation without naming an owner is an incident-time hazard. Decide who owns retries first.
  • You cannot tolerate a low bus factor and likely lag behind future Laravel majors.

Answers needed before go/no-go (1–3 are pilot-only constraints, not blockers):

  1. What do --filter and --exclude-filter match against — job class, queue, connection, batch name — and is it exact, prefix, substring, or regex?
  2. Can both flags be combined, and what wins on overlap?
  3. Is there a dry-run or count-confirmation before dispatch? Without one, this ships with a foot-gun.
  4. Does retry respect tries, maxExceptions, and allowFailures?
  5. Which Laravel/PHP versions are supported, and is there a CI matrix proving it?
  6. When the selection is empty — or every failure is excluded — does the batch reach a terminal state so catch/finally still fire?
  7. Is the command idempotent under repeated or concurrent invocation?

How to Pitch It (Stakeholders)

For executives — one paragraph: This is a small, low-cost operational improvement, not a platform bet. Today, when a background batch partially fails — a bulk import, a notification send, a data sync — recovery means either a full re-run (expensive, duplicative, customer-visible) or a manual, engineer-by-engineer script. A lightweight open-source package closes that gap: operators can retry only the failed portion of a batch, and with the 1.2.2 release, optionally exclude jobs known to be broken — so during an incident we make forward progress on the healthy part of a batch instead of waiting for a fix. Cost is a dependency line plus roughly a day of validation; if the package is ever abandoned, we replace it with a short internal script. Recommendation: adopt as internal tooling, pilot on one non-critical batch workflow, and require documented filter behavior before production use.

For engineering — the ask: Add kirschbaum-development/laravel-queue-batch-retry (^1.2, dev/ops dependency) under standard Laravel auto-discovery. It's a thin wrapper over job_batches and failed_jobs, registers an Artisan command, needs no migrations or config, and preserves batch callbacks (then/catch/finally) so bookkeeping stays correct. --exclude-filter is new in 1.2.2 and purely additive — pin at ^1.2 so it isn't silently absent on an ops box still running 1.2.1.

The work is not the install; it is characterization. Before this touches production we need, written into the retry runbook with worked examples:

  • Exactly what each filter matches, and how include and exclude compose on overlap.
  • A confirm-before-dispatch step: count the selection, then run. Both over-broad and empty selections are real incidents.
  • A check that at least one job actually re-dispatched — excluding every failure can strand a batch short of a terminal state and suppress catch/finally.
  • A single-owner convention so two operators don't run it concurrently and double-dispatch.
  • Explicit acknowledgment that retried jobs re-execute from scratch; idempotency in the job body is our responsibility, not the package's.

Boundaries to state in the same breath: single maintainer, low bus factor, likely to lag future Laravel majors — acceptable for a tool off the deploy path, not for a hard runtime dependency. Name queue:retry-batch (core, whole-batch) and Horizon as the adjacent tools, and decide which one owns retries so we don't end up with three paths to the same write. If the roadmap later calls for dependency graphs, audit trails, or approval gates, this package is not the answer, and we should say so early rather than retrofit it.

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style