Laravel Queue System Explained: Jobs, Workers & Background Processing
First, What Are Queues?
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:
- Laravel takes the job instance (
SendWelcomeEmail). - It stores it in the
jobstable (if driver = database). - 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.