What are queues?
Web applications often need to perform tasks that take several seconds to complete: sending emails, resizing images, calling external APIs, or generating reports. Running these tasks synchronously during an HTTP request means users wait until the work finishes. Laravel’s queue system lets you push these tasks to a background queue and return a response immediately. A worker process picks up the jobs and executes them separately.Laravel supports multiple queue backends—database, Redis, Amazon SQS, and more. During development, the
sync driver executes jobs immediately without a real queue, so no worker is required.Queue setup and configuration
config/queue.php
All queue configuration lives inconfig/queue.php. Switch the backend by setting the QUEUE_CONNECTION environment variable:
.env settings
Setting up the database driver
Thedatabase driver stores jobs in a database table. In Laravel 11+, new projects already include the required migration. If yours doesn’t, run:
Setting up the Redis driver
Install the Predis package and configure a Redis connection inconfig/database.php:
QUEUE_CONNECTION=redis in .env.
SQS overflow storage
Amazon SQS limits the maximum queued message payload size. If your jobs may exceed that limit, you can store oversized payloads in a cache store and send only a pointer through SQS:- When
enabledis true, payloads that are at least 1 MB are stored in the configured cache store. - When
alwaysistrue, every SQS payload is stored in the cache store regardless of size. delete_after_processingremoves stored payloads after successful processing (default:true).- If
flush_on_clearistrue,queue:clearflushes the overflow store. Use a dedicated cache store so normal cache data is not removed.
Creating and dispatching jobs
Generating a job class
Create a job with themake:job Artisan command:
app/Jobs/SendWelcomeEmail.php.
Job class structure
ShouldQueue tells Laravel to push the job onto the queue instead of running it synchronously. The Queueable trait provides the methods needed to configure and dispatch the job.
Dispatching a job
Push a job onto the queue by callingdispatch:
Dispatching to a specific queue
Send a job to a named queue to separate different priorities:Queue routing
Instead of callingonQueue() and onConnection() on every job dispatch, use the Queue facade’s route method in a service provider’s boot() to define default routing rules for specific job classes:
Queue routing can still be overridden per-dispatch with
onQueue() or onConnection().Synchronous dispatch (for testing and development)
Skip the queue and run a job immediately withdispatchSync:
Bulk dispatching
When you need to dispatch many independent jobs at once without batch tracking or callbacks, use thebulk method on the Bus facade. Laravel groups the jobs by their configured queue connection and queue name, then pushes each group to the appropriate queue in bulk:
Bus::bulk() sends jobs to the queue in bulk groups. Unlike Bus::batch(), it doesn’t provide progress tracking or completion callbacks. Use it when you want to efficiently dispatch a large number of simple, independent jobs in one call.Delayed dispatching
Delay job execution with thedelay method. Pass a DateTime or a duration:
dispatchAfterResponse runs the job right after Laravel sends the HTTP response to the browser, so the user isn’t kept waiting:
Job chaining
Chain jobs so they run sequentially. If one job in the chain fails, subsequent jobs are not run:Job batches
Batching lets you dispatch a collection of jobs and track their collective progress. Start by creating a migration for thejob_batches table:
Batchable trait in your job class:
Bus::batch:
Running the queue worker
Start a worker process with:Worker options
Setting retries and timeouts on the job class
You can configure retry and timeout behavior directly on the job using PHP attributes:Releasing jobs with middleware
Use theRelease middleware when a job should return to the queue instead of running under a particular condition.
Release::unless() releases the job when the condition is false:
Failed jobs
Preparing the failed_jobs table
When a job exceeds its maximum attempt count, Laravel records it in thefailed_jobs table. Create the table if it doesn’t exist:
Handling failure in the job
Define afailed method to run cleanup logic when a job fails:
Stopping retries by exception
Some exceptions indicate that a job should fail immediately rather than be retried. Configure these exception types usingdontRetry in bootstrap/app.php:
dontRetryWhen. When the closure returns true, the job is marked as failed immediately without further retries:
Managing failed jobs
Queue drivers compared
Example: order confirmation email
1
Create the job
2
Implement the job logic
3
Dispatch from the controller
4
Start the worker
Common use cases
When to use queues
When to use queues
- Sending email, SMS, or push notifications
- Resizing or converting images and video
- Calling slow external APIs or webhooks
- Generating reports or exporting CSV files
- Indexing records in a search engine
Development tip
Development tip
Set
QUEUE_CONNECTION=sync in your .env during development. Jobs run immediately without a worker, making it easy to test the full flow without extra processes.Common commands reference
Common commands reference