Modern web applications often need to perform tasks that take too long to run during a typical web request. Sending emails, processing images, or generating reports can slow down your app and create a poor user experience. Laravel's queue system is the elegant solution to this problem, allowing you to defer these time-consuming tasks and process them asynchronously.
This guide will take you through the entire stack, from creating a job to managing your queues like a pro with Redis and Horizon.
The Core Components: Jobs, Queues, and Workers
Let's break down the fundamental concepts.
- Jobs: A job is a small, self-contained class that represents a single task you want to run in the background. For example, ProcessPodcast or SendWelcomeEmail.
- Queues: A queue is a "to-do list" for your application. When you want to run a job later, you "dispatch" it onto a queue.
- Workers: A worker is a long-running process that constantly watches a queue. When a new job appears on the list, the worker picks it up and executes it.
Step 1: Creating a Job
Creating a job is simple with Artisan. Let's create a job to handle podcast processing.
php artisan make:job ProcessPodcast
This command generates a new file at app/Jobs/ProcessPodcast.php. The magic happens in the handle() method—this is where you put the time-consuming logic.
// app/Jobs/ProcessPodcast.php class ProcessPodcast implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $podcast; public function __construct(Podcast $podcast) { $this->podcast = $podcast; } public function handle() { // Logic to process the podcast file... // e.g., compress it, generate a transcript, etc. sleep(30); // Simulate a long-running task } }
Notice the ShouldQueue interface. This tells Laravel that this job should be pushed to the queue instead of running immediately.
Step 2: Dispatching the Job
From your controller or anywhere in your app, you can now dispatch this job.
// app/Http/Controllers/PodcastController.php use App\Jobs\ProcessPodcast; public function store(Request $request) { $podcast = Podcast::create([...]); // Dispatch the job to the queue ProcessPodcast::dispatch($podcast); return back()->with('status', 'Podcast uploaded! It will be processed shortly.'); }
The user gets an instant response, and the 30-second task runs in the background. This is the core benefit!
The Engine: Using Redis as a Queue Driver
Laravel supports several queue drivers (database, Beanstalkd, SQS), but Redis is one of the most popular choices due to its speed. Since Redis is an in-memory data store, pushing and pulling jobs from the queue is incredibly fast.
To use it, first make sure you have Redis installed and then configure your .env file:
# .env QUEUE_CONNECTION=redis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379
Now, when you dispatch a job, Laravel will automatically send it to your Redis server.
The Manager: Laravel Horizon
While you can run a basic worker from the command line with php artisan queue:work, this is difficult to monitor and manage in production. Enter Horizon.
Laravel Horizon is a beautiful dashboard and code-driven configuration system for your Redis queues. It gives you full control and insight into your queue system.
Key Features of Horizon:
- Beautiful Dashboard: A stunning UI (at /horizon) to monitor job throughput, runtime, failures, and more.
- Code-based Configuration: Configure your workers directly in the config/horizon.php file, allowing you to keep your setup in source control.
- Auto-Balancing: Horizon automatically balances worker processes across your queues based on workload.
- Metrics & Monitoring: Track key metrics like wait times and job failures to identify bottlenecks.
- Failed Job Management: Easily view and retry failed jobs directly from the dashboard.
Setting Up Horizon
Installation is straightforward:
# 1. Install Horizon via Composer composer require laravel/horizon # 2. Publish the configuration and assets php artisan horizon:install
Instead of running queue:work, you now run a single, simple command:
php artisan horizon
Horizon will read your config/horizon.php configuration and manage all your worker processes for you. It's a "set it and forget it" solution for your queue workers.
The Complete Flow
User Request (e.g., Uploads a File)
↓
Controller Dispatches a Job
↓
Job is Pushed to a Redis Queue
↓
Horizon Worker Process Picks Up the Job
↓
Job's handle() Method is Executed
↓
Task Complete!
Conclusion
By combining Laravel's native Job and Queue system with the power of Redis and the elegance of Horizon, you can build highly scalable, responsive, and resilient applications. You move from a simple request-response model to a robust system capable of handling complex, long-running tasks without ever keeping your users waiting.
If your Laravel application performs any task that can be deferred—sending emails, interacting with external APIs, processing data—then implementing this stack is not just a good idea; it's a fundamental step toward professional application architecture.
Add Comment
No comments yet. Be the first to comment!