Laravel Queue Not Running? 10 Common Causes and Fixes
Laravel queues allow you to move slow or time-consuming tasks out of the main web request. Sending emails, processing notifications, generating reports, calling external APIs, processing files, and other background tasks can all be handled by queue workers.
But sometimes you dispatch a job successfully and nothing happens.
You may see the job sitting in the jobs table, a job may fail immediately, or everything may work locally but stop processing after deployment.
This guide explains 10 common reasons Laravel queues don't run and how to troubleshoot them, including database queues, Redis, workers, failed jobs, .env configuration, and production process managers.
How Laravel Queue Processing Works
Before troubleshooting, it helps to understand the basic flow:
Application
↓
dispatch(Job)
↓
Queue Driver
↓
Queue Storage
↓
Queue Worker
↓
handle()
↓
Job completed
For example:
SendWelcomeEmail::dispatch($user);
The application puts the job onto the configured queue.
A worker such as:
php artisan queue:work
then retrieves the job and executes its handle() method.
If the worker isn't running, the job can remain in the queue indefinitely.
1. The Queue Worker Isn't Running
This is probably the most common reason.
You may dispatch:
SendWelcomeEmail::dispatch($user);
and see the job stored successfully, but nothing happens.
Start a worker:
php artisan queue:work
You should see something similar to:
INFO Processing jobs from the [default] queue.
When a job is dispatched, the worker should process it.
Check whether the worker is actually running
On Linux, you can use:
ps aux | grep "queue:work"
If you're using a process manager such as Supervisor:
sudo supervisorctl status
Important
Running queue:work in an SSH terminal is useful for testing, but it isn't a reliable production solution. If you close the terminal or the server restarts, the worker can stop.
2. Your Queue Connection Is Incorrect
Laravel uses a queue connection configured through your environment and queue configuration.
Check your .env file:
QUEUE_CONNECTION=database
or, if you're using Redis:
QUEUE_CONNECTION=redis
The important thing is that the configured driver matches the infrastructure you actually have.
For example, if you configure:
QUEUE_CONNECTION=redis
but Redis isn't running or isn't accessible, your jobs won't process correctly.
Check the current configuration
You can inspect Laravel's queue configuration:
php artisan config:show queue
This is useful when you aren't sure what connection Laravel is actually using.
3. Configuration Cache Contains an Old Queue Setting
This is a particularly common production problem.
You change:
QUEUE_CONNECTION=database
but Laravel continues behaving as though another driver is configured.
Why?
Because Laravel may be using cached configuration.
Clear the configuration cache:
php artisan config:clear
Then verify the configuration again.
For a production deployment where you intentionally cache configuration:
php artisan config:cache
A common deployment mistake
You deploy:
.env changed
↓
git pull
↓
restart application
but forget that the server is still using previously cached configuration.
When debugging queue problems, always consider configuration caching.
4. The Database Queue Tables Don't Exist
If you're using the database queue driver:
QUEUE_CONNECTION=database
Laravel needs the appropriate queue tables.
Depending on your Laravel application's migration setup, you may need to create the jobs table with Artisan:
php artisan make:queue-table
Then run:
php artisan migrate
Your database should contain the queue table used by your configured setup, commonly:
jobs
You can check whether jobs are actually being inserted:
SELECT * FROM jobs ORDER BY id DESC;
If jobs are appearing there but never disappearing, that is a strong indication that your worker isn't processing them.
5. The Worker Is Listening to the Wrong Queue
Laravel allows jobs to be placed on named queues.
For example:
SendReport::dispatch($report)
->onQueue('reports');
But if your worker only listens to another queue, it won't process that job.
For example:
php artisan queue:work --queue=default
will listen to the default queue.
It won't necessarily process jobs waiting on reports.
Start the worker with the appropriate queues:
php artisan queue:work --queue=reports,default
Check your job configuration
Look for code such as:
public $queue = 'reports';
or:
->onQueue('reports')
Make sure your worker is configured to consume that queue.
6. The Job Is Failing Immediately
Sometimes the worker is running, but the job fails every time.
Check failed jobs:
php artisan queue:failed
You'll get information about failed jobs, including their IDs and exception details.
To inspect a failed job, check your application's logs:
storage/logs/laravel.log
You may find errors such as:
SQLSTATE...
Class not found...
Call to undefined method...
Connection refused...
Authentication failed...
Retry a failed job
After fixing the underlying problem:
php artisan queue:retry <id>
For example:
php artisan queue:retry 15
You can also retry all failed jobs:
php artisan queue:retry all
Don't repeatedly retry jobs without fixing the underlying error. Otherwise, you'll simply generate the same failure again.
7. Redis Is Not Running or Cannot Be Reached
If you're using Redis:
QUEUE_CONNECTION=redis
your Laravel application needs access to the Redis server.
A typical setup might contain:
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
Check whether Redis is reachable.
For example:
redis-cli ping
A healthy Redis server should respond:
PONG
If you're running Laravel and Redis in Docker, 127.0.0.1 can be a common mistake.
Inside a Docker container, 127.0.0.1 refers to that container itself, not necessarily the Redis container.
You may instead need something like:
REDIS_HOST=redis
where redis is the Docker Compose service name.
8. The Worker Stops After a Deployment
A common production scenario looks like this:
Application works
↓
New code deployed
↓
git pull
↓
Laravel updated
↓
Queue worker still running old code
Laravel queue workers are long-running processes. They don't automatically reload your application code every time you change a file.
After deployment, restart workers gracefully:
php artisan queue:restart
Laravel signals workers to finish their current jobs and restart.
If you're using Supervisor, you may also need to make sure Supervisor brings the workers back up correctly.
For example:
sudo supervisorctl restart laravel-worker:*
The exact Supervisor process name depends on your configuration.
Important
Don't casually kill production workers while they're processing important jobs. A graceful restart is generally preferable.
9. The Worker Times Out or Gets Stuck
Some jobs take longer than others.
For example:
- Large file processing
- Image processing
- External API requests
- Large report generation
- Complex database operations
A worker may terminate a job if it exceeds its configured timeout.
You can specify a worker timeout:
php artisan queue:work --timeout=120
This allows the worker to run a job for up to the configured period before timing it out.
However, increasing the timeout isn't always the correct solution.
If a job takes several minutes because it processes thousands of records at once, consider breaking the work into smaller jobs.
For example:
Process 100,000 records
↓
10 jobs × 10,000
can often be better than one massive job.
10. Supervisor Is Not Managing the Worker Correctly
For production Laravel applications, you generally want your queue workers to run continuously.
A process manager such as Supervisor can:
- Start workers automatically
- Restart workers after crashes
- Start them after server reboot
- Manage multiple workers
A simplified Supervisor configuration might look like:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/example.com/artisan queue:work --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/example.com/storage/logs/worker.log
stopwaitsecs=3600
After changing Supervisor configuration, reload it:
sudo supervisorctl reread
sudo supervisorctl update
Then check:
sudo supervisorctl status
You want to see your worker processes running.
Important
The exact paths, user, PHP executable, and number of workers should be adjusted for your server.
Don't copy a production Supervisor configuration blindly.
How to Quickly Diagnose a Laravel Queue Problem
When someone says:
"My Laravel queue isn't working."
Don't immediately reinstall Laravel or Redis.
Start with these checks.
Step 1: Check the queue connection
php artisan config:show queue
Step 2: Check whether jobs exist
For a database queue:
SELECT * FROM jobs ORDER BY id DESC;
Step 3: Start a worker manually
php artisan queue:work -v
The -v option can provide more information while troubleshooting.
Step 4: Check failed jobs
php artisan queue:failed
Step 5: Check Laravel logs
storage/logs/laravel.log
Step 6: Check your process manager
If using Supervisor:
sudo supervisorctl status
Step 7: Check external dependencies
If the job communicates with:
- Redis
- MySQL/PostgreSQL
- SMTP
- S3
- Another API
make sure those services are actually reachable from the worker environment.
A Simple Test Job
If you're unsure whether your queue is working at all, create a small test job.
Create one:
php artisan make:job TestQueueJob
Then inside the job:
public function handle(): void
{
\Log::info('Laravel queue test job executed successfully.');
}
Dispatch it:
TestQueueJob::dispatch();
Then start the worker:
php artisan queue:work
Check:
storage/logs/laravel.log
You should find:
Laravel queue test job executed successfully.
This separates a queue infrastructure problem from a problem inside your actual application job.
Database Queue vs Redis Queue
Both are useful, but they have different characteristics.
| Feature | Database | Redis |
|---|---|---|
| Setup | Simple | Requires Redis |
| Good for small apps | ✅ | ✅ |
| Performance | Moderate | Very fast |
| Infrastructure | MySQL/PostgreSQL | Redis |
| Easy to inspect | ✅ | Less direct |
| High-volume queues | Less ideal | ✅ |
For a smaller Laravel application, the database queue can be perfectly adequate.
For applications processing a large number of jobs, Redis is often a better choice.
Production Laravel Queue Checklist
Before considering your queue setup complete, verify:
✓ QUEUE_CONNECTION is correct
✓ Configuration cache is current
✓ Queue tables exist if using database
✓ Redis is running if using Redis
✓ Worker is running
✓ Worker listens to the correct queue
✓ Failed jobs are being monitored
✓ Job timeout is appropriate
✓ External services are reachable
✓ Workers are restarted after deployments
✓ Supervisor/systemd manages production workers
✓ Laravel logs are monitored
Final Thoughts
A Laravel queue that isn't processing jobs doesn't necessarily mean Laravel is broken.
The problem is usually somewhere in the chain:
Job dispatched
↓
Correct queue connection?
↓
Job stored?
↓
Worker running?
↓
Correct queue?
↓
Job succeeds?
↓
Worker managed in production?
If you work through these steps in order, you can usually identify the problem much faster.
The most important commands to remember are:
php artisan queue:work
php artisan queue:failed
php artisan queue:retry all
php artisan queue:restart
php artisan config:show queue
php artisan config:clear
And for production:
sudo supervisorctl status
Don't simply restart everything whenever a queue stops. Find out whether the problem is the queue driver, stored jobs, worker, job code, dependency, or process manager first.
