Distinguishing between a user-canceled batch and a failed batch matters. Same cancelled() state, different intent. failedJobs === 0 is how you tell them apart and route cleanup correctly.
If you're working in Laravel for the first time, this is worth watching. No assumed knowledge, just practical implementation. codecourse.com/courses/getti…
This week: canceling a running batch, skipping jobs with middleware, and using the finally callback to tell the difference between cancellation and failure. Episode is up. youtu.be/6aHEJSviWt4
How are you handling cleanup when a batch gets canceled mid-run? Curious whether people are leaning on the finally callback, model events, or something else entirely.
You can check $this->batch()->cancelled() inside a job and return early. It works. But doing that in every job is the kind of repetition that middleware exists to eliminate.
Everyone's talking about background AI agents running autonomous tasks. The boring infrastructure problem: what happens when you need to stop one mid-run. Laravel's batch cancellation is a good place to start thinking about this.
Bus::findBatch($id) is how you get a handle on a running batch. Worth putting a helper method on your model so you're not scattering that lookup across your codebase.
If you're learning Laravel, here's a new episode in the Getting Started with Laravel course. codecourse.com/courses/getti…
What course topic do you want to see next?
New Youtube Video! we're looking at something that comes up the moment you start building anything with job batches in Laravel — what happens when you need to stop mid-run. The episode drops Friday. youtu.be/6aHEJSviWt4
The pattern here is simple: interface defines the contract, job implements it, trait reads from it at dispatch, database stores it. Each layer does one thing.
At what point does a jobs table become a lightweight audit log? If you're storing state, title, description, and failure reasons — that's getting close. Where do you draw the line?
On failure, update the current task row with a description pulled from the exception. The infrastructure for this is already there once you have title and description in place — it's just one more column.
Job metadata isn't just for display. A failed_reason column on server_tasks lets you capture exception data at failure time and surface it later — without digging through logs.
Once your job titles are dynamic and stored at dispatch time, reloading the page is trivial. Iterate over server_tasks, output title — done. No front-end mapping, no hardcoded copy.
Set the server as protected in the constructor. You'll need it for the actual job logic anyway, so you're not adding the parameter purely for metadata — it's doing double duty.
This week was about attaching metadata to Laravel jobs so your UI doesn't need to hardcode anything. Title, description, dynamic values from the model — all stored at dispatch time. Full episode: youtu.be/9rrz4MhmXGY
This week: storing metadata on queued jobs, enforcing a title/description interface, and making job labels dynamic from the model. The full episode is on YouTube: youtu.be/9rrz4MhmXGY