Introduction
In web applications, certain tasks—such as sending emails, processing large datasets, or making API calls—can be time-consuming. Running them synchronously can slow down the application, resulting in poor user experience and performance issues.
Laravel provides queues as a way to handle these tasks asynchronously, ensuring that requests remain fast and responsive while executing background jobs efficiently.
In this guide, we’ll cover:
✅ What Laravel Queues are and why they are useful
✅ How to configure and use Laravel’s queue system
✅ Setting up queue workers and drivers
✅ Error handling and queue monitoring
By the end, you’ll be able to implement and optimize queues in your Laravel projects.
What Are Queues in Laravel?
Queues in Laravel allow jobs to be processed in the background instead of blocking the main request-response cycle. They work by pushing tasks into a queue and processing them asynchronously using a worker.
Why Use Queues?
✅ Improves Performance – Long-running tasks do not slow down user interactions.
✅ Enhances Scalability – Background jobs can be distributed across multiple workers.
✅ Ensures Reliability – Jobs can be retried if they fail.
✅ Optimizes Resource Usage – Frees up server resources for handling user requests.
Common Use Cases for Queues
- Sending emails or notifications
- Processing file uploads or image resizing
- Running large database operations
- Integrating with third-party APIs
- Handling scheduled tasks and reports
Step 1: Configuring Laravel Queues
Laravel supports multiple queue drivers, including:
- Database – Stores jobs in a database table.
- Redis – High-performance queue using Redis.
- Amazon SQS – Scalable queue service from AWS.
- Beanstalkd – A fast work queue for simple job management.
- Sync – Executes jobs immediately (useful for testing).
Configuring the Queue Driver
Set the preferred driver in .env
:
QUEUE_CONNECTION=database
Then, publish the queue configuration file:
php artisan queue:table
php artisan migrate
This creates a jobs
table to store queued tasks when using the database driver.
Step 2: Creating and Dispatching Jobs
Jobs in Laravel handle specific tasks in the background.
Creating a Job Class
Use Artisan to generate a new job:
php artisan make:job ProcessOrder
This creates a file in app/Jobs/ProcessOrder.php
. Modify the handle()
method to define the job’s logic:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\Order;
class ProcessOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $order;
public function __construct(Order $order)
{
$this->order = $order;
}
public function handle()
{
// Process order logic
$this->order->update(['status' => 'processed']);
}
}
Dispatching a Job
Jobs can be dispatched from controllers or services like this:
use App\Jobs\ProcessOrder;
use App\Models\Order;
$order = Order::find(1);
ProcessOrder::dispatch($order);
This pushes the job into the queue, where it will be processed asynchronously.
Step 3: Running the Queue Worker
To process queued jobs, start a queue worker:
php artisan queue:work
This command continuously listens for new jobs and executes them.
For production, use supervisor to manage queue workers efficiently:
sudo apt install supervisor
Configure a supervisor queue worker (/etc/supervisor/conf.d/laravel-worker.conf
):
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path-to-project/artisan queue:work --tries=3
autostart=true
autorestart=true
numprocs=3
redirect_stderr=true
stdout_logfile=/path-to-project/storage/logs/worker.log
Restart the supervisor service:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
✅ Use Supervisor to keep queue workers running persistently in production.
Step 4: Handling Failed Jobs
If a job fails, Laravel can track it in the failed_jobs
table. Enable it by running:
php artisan queue:failed-table
php artisan migrate
To retry failed jobs:
php artisan queue:retry all
To manually delete failed jobs:
php artisan queue:forget {id}
For automatic job retries, add --tries=3
when running the queue worker:
php artisan queue:work --tries=3
✅ Always monitor failed jobs to ensure application reliability.
Step 5: Prioritizing and Delaying Jobs
Prioritizing Queues
Laravel allows multiple queue connections. Assign high-priority jobs to a high
queue:
ProcessOrder::dispatch($order)->onQueue('high');
Run workers with priority queues:
php artisan queue:work --queue=high,default
Delaying Jobs
Jobs can be delayed to execute after a certain period:
ProcessOrder::dispatch($order)->delay(now()->addMinutes(10));
✅ Use queue prioritization to manage workload distribution efficiently.
Best Practices for Laravel Queues
✅ Use the right queue driver – Database for small applications, Redis for high-performance tasks.
✅ Run queue workers using Supervisor in production to keep them alive.
✅ Handle job failures properly by monitoring failed_jobs
.
✅ Prioritize jobs to process critical tasks first.
✅ Use caching for frequently accessed data to reduce database hits.
✅ Monitor queue performance using Laravel Horizon for Redis queues.
Conclusion
Laravel Queues offer a powerful and scalable way to handle background tasks efficiently. By leveraging queues, workers, and proper job management, you can drastically improve application performance and user experience.
By implementing best practices, prioritization, and monitoring, Laravel queues will help keep your application responsive, reliable, and scalable. 🚀