April 08, 2026

Mastering Asynchronous Processing: Scaling B2B SaaS with Laravel Queues and Horizon

By Paresh Prajapati • Lead Architect

Mastering Asynchronous Processing: Scaling B2B SaaS with Laravel Queues and Horizon

The Silent Killer of Application Performance

In the early days of building a SaaS application, it is tempting to execute everything synchronously. A user requests a massive data export, and your controller handles the database query, formats the CSV, uploads it to an S3 bucket, and emails the user—all within the same HTTP request. As your platform grows, this approach guarantees timeouts, frustrated users, and server crashes.

For durable B2B platforms like those we build at Smart Tech Devs, moving heavy processing to the background is not optional; it is mandatory. Laravel’s robust Queue system, powered by Redis and monitored by Laravel Horizon, provides the enterprise-grade infrastructure needed to handle asynchronous tasks flawlessly.

Architecting Background Jobs

The goal is to respond to the user's HTTP request immediately, acknowledging that the task has started, while the heavy lifting happens on a separate worker process.

Step 1: Creating a Dedicated Job Class

Instead of placing logic in the controller, we isolate the heavy task into a Job class. In this scenario, generating a complex end-of-month financial report for a tenant.


namespace App\Jobs;

use App\Models\Tenant;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Services\ReportingService;
use Mail;

class GenerateMonthlyFinancialReport implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tenant;
    public $month;

    // Define specific queue parameters
    public $tries = 3;
    public $timeout = 120; // 2 minutes max execution time

    public function __construct(Tenant $tenant, string $month)
    {
        $this->tenant = $tenant;
        $this->month = $month;
    }

    /**
     * Execute the heavy job.
     */
    public function handle(ReportingService $reporting): void
    {
        // 1. Perform massive database queries and calculations
        $reportPath = $reporting->generateCsvForTenant($this->tenant, $this->month);

        // 2. Email the secure link to the tenant admin
        Mail::to($this->tenant->admin_email)->send(new \App\Mail\MonthlyReportReady($reportPath));
    }
}

Step 2: Dispatching the Job from the Controller

The controller now becomes incredibly lightweight. It simply dispatches the job to the queue and instantly returns a 202 Accepted response to the frontend UI.


public function exportReport(Request $request)
{
    $tenant = $request->user()->tenant;
    
    // Push the job to a specific, high-priority Redis queue
    GenerateMonthlyFinancialReport::dispatch($tenant, $request->month)
        ->onQueue('reports');

    return response()->json([
        'status' => 'processing',
        'message' => 'Your report is being generated. We will email you when it is ready.'
    ], 202);
}

Gaining Visibility with Laravel Horizon

Pushing jobs to Redis is easy, but managing them at scale requires visibility. Laravel Horizon provides a beautiful dashboard and code-driven configuration for your Redis queues. It allows you to monitor job throughput, track failed jobs, and set up auto-balancing.

Instead of manually starting generic queue workers, Horizon allows you to define worker pools in your config/horizon.php file. You can allocate 10 processes to your fast emails queue and only 2 processes to your heavy reports queue, ensuring that a backlog of massive PDF exports doesn't stop password reset emails from going out.

Conclusion

Embracing asynchronous processing is a critical milestone in backend architecture. By leveraging Laravel Queues and Horizon, you protect your application's main thread, drastically improve user perceived performance, and build a system capable of handling enterprise-level workloads without breaking a sweat.

Paresh Prajapati
Lead Architect, Smart Tech Devs