Modern Laravel applications rely heavily on background jobs. Emails, payments, notifications, webhooks, and third-party API calls all run inside queues to keep user requests fast.
But what happens when an external service goes down?
If Mailgun, Stripe, or another API becomes slow or unavailable, your queue workers keep retrying. Jobs hang, time out, retry again, and slowly your entire queue becomes clogged. This is how a small outage turns into a system-wide bottleneck.
Laravel Fuse solves this problem by implementing a circuit breaker for queue jobs.
This article explains:
- What laravel fuse is?
- The problem it solves.
- When to use it?
- How it works internally?
- How to install and configure it?
- A real example.
- Trade-offs and limitations.
The Problem: Cascading Failures in Queue Systems
- Queues are meant to improve performance and reliability. But they depend on external services behaving correctly.
Imagine this flow:
- Your app queues 5,000 email jobs
- Your email provider is down
- Each job waits for timeout (10–30 seconds)
- Jobs retry multiple times
- Workers get stuck processing failures
- New jobs pile up behind them
- This is called a cascading failure. One dependency failure spreads and damages the entire system.
- Without protection, your queue becomes a traffic jam.
- You don’t want your app waiting politely for a dead service. You want it to detect failure early and move on.
That’s exactly what Laravel Fuse does.

What Is Laravel Fuse?
Laravel Fuse is a package that applies the circuit breaker pattern to Laravel queue jobs.
A circuit breaker acts like an electrical fuse:
- When failures exceed a safe threshold → it “blows”
- Calls to the failing service stop immediately
- The system waits before trying again
- Instead of letting jobs hang and retry endlessly, Fuse fails fast and protects the queue.
- It does not replace Laravel queues.
- It wraps jobs with intelligent failure protection.
Why It Is Used?
Laravel Fuse exists to protect system stability.
It helps you:
- prevent queue congestion
- reduce wasted timeouts
- isolate failing services
- maintain throughput
- recover automatically when services return
- The goal is graceful degradation.
- Even if one dependency dies, the rest of your system keeps working.
When You Should Use Laravel Fuse?
Laravel Fuse is especially useful when:
- Calling unreliable third-party APIs
- Sending emails through external providers
- Processing payment gateways
- Running webhook integrations
- Handling high-volume background tasks
- Building systems where queue uptime matters
- If a job touches an external service you don’t control, it’s a candidate for Fuse.

How the Circuit Breaker Works?
Laravel Fuse follows the classic circuit breaker model with three states:
- CLOSED (Normal State)
- Jobs run normally.
- Failures are monitored.
- System is healthy.
- OPEN (Protection Mode)
- Too many failures occurred.
- Fuse stops allowing calls.
- Jobs fail instantly instead of waiting.
- This prevents queue lockup.
- HALF-OPEN (Testing Recovery)
- Fuse allows a small number of test calls.
- If they succeed → circuit closes.
- If they fail → circuit opens again.
- This automatic recovery makes the system self-healing.
- You don’t need manual intervention.
Real-World Impact
Using Laravel Fuse:
- Keeps queue workers responsive.
- Protects throughput during outages.
- Prevents timeout storms.
- Improves background job reliability.
- Reduces infrastructure strain.
- Instead of thousands of hanging jobs, failures are controlled and fast.
- This is the difference between a degraded system and a broken system.

Illustration of Laravel Fuse:
composer require harris21/laravel-fuse
Step 1: Install the package by running following command:
Step 2: Publish configuration:
php artisan vendor:publish --tag=fuse-config
This creates:
config/fuse.php
Step 3: Configure fuse.php[Text Wrapping Break]
- Here we consider mail as the service, you can add stripe or anything as your service, whichever you are using.
'services' => [
'mail' => [
'failure_threshold' => 5,
'retry_timeout' => 60, [Text Wrapping Break]],
],
This means:
- 5 failures → circuit opens
- waits 60 seconds before testing recovery
Step 4: Adding fuse protection in the Queue job
- We consider that queue has already been setup with basic details and the service you are using within the queue is properly setup.
- The following command will create the queue file.
php artisan make:job SendWelcomeEmail
SendWelcomeEmail.php
<?php
namespace App\Jobs;
use App\Helpers\Helper;
use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Harris21\Fuse\Middleware\CircuitBreakerMiddleware;
class SendWelcomeEmail implements ShouldQueue
{
public $tries = 0;
public $maxExceptions = 3;
public function __construct(public User $user) {}
public function middleware(): array
{
return [
new CircuitBreakerMiddleware('mail')
];
}
public function handle()
{
Helper::sendWelcomeMail([
'email' => $this->user->email,
'user' => $this->user
]);
}
}

Helper.php
<?php
namespace App\Helpers;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class Helper
{
public static function sendWelcomeMail($data)
{
$mail = new PHPMailer(true);
try {
/* Email SMTP Settings */
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = env('MAIL_HOST');
$mail->SMTPAuth = true;
$mail->Username = env('MAIL_USERNAME');
$mail->Password = env('MAIL_PASSWORD');
$mail->SMTPSecure = env('MAIL_ENCRYPTION');
$mail->Port = env('MAIL_PORT');
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
$mail->setFrom(env('MAIL_FROM_ADDRESS'), env('MAIL_FROM_NAME'));
$mail->addAddress($data['email']);
$mail->isHTML(true);
$mail->Subject = 'Welcome!';
$html = view('emails.welcome', $data);
$mail->Body = $html;
if (!$mail->send()) {
return "Email not sent.";
} else {
return "Email has been sent.";
}
} catch (Exception $e) {
return 'Message could not be sent.';
}
}
}
welcome.blade.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome</title>
</head>
<body>
<h2>Welcome {{ $user->name }}</h2>
<p>
Hello {{ $user->name }},
</p>
<p>
Your account has been successfully created.
</p>
<p>
Registered email: {{ $email }}
</p>
<p>
Thank you for joining us!
</p>
</body>
</html>
Conclusion:
By adding Laravel Fuse to our background email job, we protected the queue from breaking when the mail service fails, while still keeping our PHPMailer workflow intact. This small layer of resilience ensures emails fail fast, recover automatically, and the rest of the system keeps running smoothly.
