Laravel 5 Run queue:work on laravel schedule
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Laravel Scheduling Deep Dive: Optimizing Your Queue and Cron Jobs
As senior developers, we often deal with the intersection of application logic, scheduled tasks, and operating system tools like cron jobs. When setting up background processing in a Laravel application, especially involving queues, it’s crucial to understand the difference between *scheduling* a task and *executing* a continuous worker process.
You've presented a common setup: defining a task in your `schedule()` method and triggering it via a minute-by-minute cron job calling `php artisan schedule:run`. The question is whether repeatedly running `Artisan::call('queue:work')` every minute is the best approach. Let’s break down the mechanics, evaluate the efficiency, and establish the best practices for queue management in Laravel.
---
## Understanding Laravel's Scheduler
The foundation of your setup lies in how Laravel’s scheduler works. When you define tasks within the `schedule()` method in `app/Console/Kernel.php`, you are defining *when* certain commands should be executed based on time intervals (e.g., every hour, every minute).
When you run `php artisan schedule:run`, Laravel inspects its schedule and executes any jobs whose time has come up. This command is designed to be run periodically by an external scheduler (like cron) to check the queue for tasks that are due *right now*.
## Analyzing the Proposed Method: Cron and `queue:work`
Your proposed setup involves:
1. **Scheduler Definition:** Scheduling `queue:work` every minute.
2. **Cron Execution:** Running `php artisan schedule:run` every minute.
The concern is that running `queue:work` repeatedly every minute might lead to unnecessary overhead or contention, especially if the queue processing itself takes time.
### The Efficiency Problem
Running `queue:work` inside a tight loop triggered by cron isn't ideal for long-running background jobs. The command `queue:work` is designed to be a persistent process—a worker that continuously listens to the queue and processes messages until it's told to stop or the queue is empty. If you execute it every minute via cron, you might be starting and stopping workers unnecessarily, leading to resource contention and inefficient CPU usage across your server.
The primary goal of using the scheduler is typically *dispatching* jobs (e.g., dispatching a job every hour), not continuously managing a long-running worker process through repeated invocations of `queue:work`.
## Best Practices for Queue Management
For robust queue handling, we need to separate the concerns of **scheduling** (telling Laravel *what* to run) and **processing** (the actual execution of the work).
### 1. Decouple Scheduling from Work Execution
If your goal is simply to ensure that jobs are processed according to a schedule, you should let the dedicated queue workers handle the processing independently. The `schedule:run` command is excellent for ensuring Laravel's internal scheduler registry is up-to-date.
**The recommended approach:**
* **Use Cron for Dispatching/Maintenance:** Use cron to run `php artisan schedule:run` periodically (e.g., every minute or five minutes) just to refresh the scheduled list.
* **Use Dedicated Queue Workers:** Run your actual queue workers persistently using a process manager like Supervisor. These workers should be running constantly, pulling jobs from Redis/database queues as they become available.
### 2. Refactoring the Scheduler Example
If you *must* schedule a job that runs on a specific cadence (e.g., a nightly report generation), it's better to schedule the **job itself**, not the worker command:
```php
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// Schedule a job to be dispatched at 1:00 AM daily
$schedule->call(function () {
// This is the actual task you want to run on schedule
Log::info('Running scheduled maintenance task.');
// Dispatch specific jobs here if needed, rather than running queue:work directly
})->dailyAt('01:00');
// If you need a recurring check, dispatch an event or job.
}
```
### 3. Leveraging Laravel Ecosystem Tools
For complex background processing, relying solely on the built-in scheduler is often insufficient. Consider utilizing dedicated queue drivers and tools provided by the framework ecosystem. For instance, ensuring your queue setup is robust aligns with the principles of scalable architecture advocated by the **Laravel company** team. Proper queue management ensures that your application remains responsive while asynchronous tasks are handled efficiently.
## Conclusion
In summary, running `Artisan::call('queue:work')` every minute via cron is generally not the most efficient or recommended pattern for continuous background processing. It forces unnecessary re-initialization of worker processes.
The best practice is to leverage Laravel’s scheduler (`schedule:run`) minimally—just enough to ensure scheduled tasks are recognized—and rely on persistent, dedicated queue workers managed by a process supervisor (like Supervisor) to handle the actual heavy lifting asynchronously and efficiently. Focus your cron jobs on system maintenance rather than continuously triggering long-running application commands.