The Ultimate Guide to Laravel Task Scheduling and Queues
Laravel's task scheduling and queueing systems provide powerful tools for managing background jobs and automating repetitive tasks. In this guide, we'll cover everything you need to set up a robust task scheduling and queue system, from configuring the cron heartbeat to monitoring your queues with Laravel Horizon.
1. Setting Up the Cron Heartbeat for schedule:run
Laravel's task scheduler relies on a single cron entry to run the schedule:run command every minute. This command checks your defined scheduled tasks and executes any that are due.
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Steps to set up:
- SSH into your server.
- Run
crontab -eto edit your cron jobs. - Add the above line, adjusting the path to your Laravel
artisanfile. - Save and exit.
This single line ensures Laravel's scheduler runs every minute, executing scheduled tasks defined in app/Console/Kernel.php.
2. Choosing the Right Queue Driver
Laravel supports several queue drivers. Choosing the right one depends on your application's scale, infrastructure, and performance needs.
Database Driver
- Pros: Simple setup, no external dependencies.
- Cons: Less performant under heavy load.
- Use case: Small to medium applications or development environments.
Redis Driver
- Pros: Fast, supports advanced features like delayed jobs.
- Cons: Requires Redis server setup.
- Use case: High-performance applications.
Laravel Horizon
- Horizon is a dashboard and queue manager built specifically for Redis queues.
- Provides real-time monitoring, metrics, and job management.
- Ideal for production environments running Redis queues.
Configuring your queue driver: In config/queue.php, set the default key to your preferred driver, e.g., 'redis' or 'database'.
3. Handling Job Failures and Retries
Robust queue systems need to handle failures gracefully. Laravel provides tries and backoff properties to control job retries.
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessOrder implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 5;
/**
* The number of seconds to wait before retrying the job.
*
* @var int|array
*/
public $backoff = [60, 120, 300];
public function handle()
{
// Job logic here
}
public function failed()
{
// Handle failure, e.g., notify admin
}
}
$triesdefines max retry attempts.$backoffsupports fixed seconds or progressive delays using arrays.- Implement a
failed()method to handle when all retries are exhausted.
4. Monitoring Queues in Real-Time with Laravel Horizon
Laravel Horizon offers a beautiful dashboard for monitoring Redis queues. It provides insights into job throughput, failures, runtime, and allows you to configure worker processes.
Installation and Setup
composer require laravel/horizon
php artisan horizon:install
php artisan migrate
Publish Horizon's assets and configuration:
php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"
Start Horizon with:
php artisan horizon
Configuring Workers
Edit config/horizon.php to define your worker pools and queue worker settings, including concurrency and balancing strategies.
Accessing the Dashboard
By default, the Horizon dashboard is accessible via /horizon URL. Protect it with middleware to restrict access.
5. PHP Worker Management Best Practices
- Daemon queue workers: Run workers as daemons to keep processes alive for performance.
- Supervisor: Use process monitors like
supervisordor systemd to keep workers running. - Memory limits: Set memory limits to avoid leaks (
--memoryoption). - Timeouts: Configure job timeouts to prevent hanging workers.
Example Supervisor configuration:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path-to-your-project/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
numprocs=3
redirect_stderr=true
stdout_logfile=/path-to-your-project/storage/logs/worker.log
Conclusion
By setting up the cron heartbeat, choosing the right queue driver, handling job failures effectively, and monitoring your queues with Laravel Horizon, you can build resilient and efficient background job processing in your Laravel applications. Follow best practices for worker management to maintain uptime and performance.
Explore Laravel's official docs and Horizon repository for deeper dives and updates.