Featured blog image
607 words 4 min read

Laravel Queue System Explained: Jobs, Workers & Background Processing

First, What Are Queues?

Let’s look at the problem queues are meant to solve. Imagine you have a registration page where a new user signs up, and after signing up, you send them a welcome email.
If the email is sent directly inside the same request, the user will have to wait until the email is fully processed — which may take a couple of seconds.
This results in a bad user experience.

The solution?
Instead of sending the email immediately, Laravel allows you to add the process (SendWelcomeEmail) to a Queue.
This means: “Execute this task later in the background, but return a response to the user right away.”

In Simple :

Queue = A list of tasks waiting for execution.

Job = The task itself (a small piece of code that performs a specific action).

Worker = The process that picks up jobs from the queue and executes them in the background.


Why is this useful?

Performance Boost — The main request returns instantly to the user.

Load Distribution — The server executes tasks gradually instead of all at once.

Reliability — If a job fails, Laravel can retry it or mark it as failed.


Setting Up Queues in Laravel

To enable queues in Laravel, you need to define the driver — which determines where the jobs will be stored.

sync → Executes the job instantly (no actual queue used).

database → Stores the jobs in a table within your database.

redis → Fast and suitable for high workloads.


Editing the .env File

Open the .env file and modify this line:

QUEUE_CONNECTION=database

Configuring config/queue.php

This file contains all configuration for each driver under the connections section:

'connections' => [
    'sync' => [
        'driver' => 'sync',
    ],

    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 90,
    ],
],
  • driver: The name of the driver being used (database, sync, redis, etc.).
  • table: The name of the table where jobs will be stored.
  • retry_after: Time (in seconds) before Laravel considers a job failed if not completed.

Create the Jobs Table

Since we’re using the database driver, we need to create the jobs table:

php artisan queue:table
php artisan migrate

This command creates a jobs table containing information about pending tasks.


Create a Job in Laravel

The Job is the actual code piece added to the queue — it defines what should be executed in the background.

Let’s create a new Job for our example:

php artisan make:job SendWelcomeEmail

This generates a new file at:

app/Jobs/SendWelcomeEmail.php

Here’s the default structure:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

    public function __construct(public $user) {}

    public function handle(): void
    {
        // The code to execute goes here
    }
}

In your controller, you can dispatch the job like this:

SendWelcomeEmail::dispatch($user);

Sending the Job to the Queue

As we saw, the dispatch() method adds the job to the queue:

SendWelcomeEmail::dispatch($user);

Here’s what happens:

  1. Laravel takes the job instance ( SendWelcomeEmail ).
  2. It stores it in the jobs table (if driver = database).
  3. The worker then picks it up later for execution.

Running the Worker

This is the process that continuously listens for jobs and executes them:

php artisan queue:work

To execute just one job and stop:

php artisan queue:work --once


Restarting Workers

If you modify job code during development, restart the workers to apply changes:

php artisan queue:restart

Laravel sends a signal to all workers, asking them to finish their current tasks and then restart gracefully.

Handling Failed Jobs in Laravel Queue


Share Now ?
Let's chat