Fuse for Laravel: A Circuit Breaker for Queue Jobs
Here is a failure scenario most Laravel developers have either experienced or will experience. Stripe goes down at 11 PM. Your queue workers do not know this. They keep picking up jobs, each one waiting 30 seconds for a timeout before retrying. With 10,000 jobs in the queue, that is over 25 hours to clear the backlog once Stripe recovers. Your queue is effectively frozen for the rest of the night.
Fuse is a new Laravel package that addresses this with the circuit breaker pattern. After a configurable number of failures, the circuit opens. Jobs that would have hit the downed service fail instantly (in under a millisecond rather than after a 30-second timeout) and are delayed for automatic retry. When the service recovers, the circuit closes and the queue clears. The same 10,000-job scenario takes around 10 seconds to process once the circuit is protecting it.
How to Add It
Installation is a composer package:
composer require harris21/laravel-fuse
You then add the middleware to any job that calls an external service:
use Harris21\Fuse\Middleware\CircuitBreakerMiddleware;
class ChargeCustomer implements ShouldQueue
{
public $tries = 0; // Unlimited releases
public $maxExceptions = 3; // Only real failures count
public function middleware(): array
{
return [new CircuitBreakerMiddleware('stripe')];
}
public function handle(): void
{
Stripe::charges()->create([...]);
}
}
That is the entire integration. Your job logic is unchanged.
Sensible Defaults
A few details in the implementation are worth noting. Fuse distinguishes between real outages and other error types: 429 rate limit responses, 401 authentication errors, and 403 forbidden responses do not count as failures and will not trip the circuit. Only actual server errors and connection failures do. This prevents a misconfigured API key from triggering circuit protection that should only activate during genuine downtime.
There is also a peak hours configuration that lets you set different thresholds for business hours versus off-peak, which is useful if your application processes higher-value transactions during the day and you want the circuit to be more tolerant of occasional failures during that window.
Jobs are delayed using release() rather than failed permanently, which means no data loss. There is also built-in thundering herd prevention using Cache::lock() to ensure only one worker probes the service during the half-open recovery phase, and a monitoring dashboard for tracking circuit state in real time.
If you have queue jobs that call third-party APIs, this is a straightforward addition that removes an entire class of cascading failure. Source on GitHub.
