Auto than long bị lỗi has been working năm 2024

While building your web application, you may have some tasks, such as parsing and storing an uploaded CSV file, that take too long to perform during a typical web request. Thankfully, Laravel allows you to easily create queued jobs that may be processed in the background. By moving time intensive tasks to a queue, your application can respond to web requests with blazing speed and provide a better user experience to your customers.

Laravel queues provide a unified queueing API across a variety of different queue backends, such as Amazon SQS, Redis, or even a relational database.

Laravel's queue configuration options are stored in your application's


php artisan queue:work --queue=high,default

44 configuration file. In this file, you will find connection configurations for each of the queue drivers that are included with the framework, including the database, Amazon SQS, Redis, and Beanstalkd drivers, as well as a synchronous driver that will execute jobs immediately (for use during local development). A


php artisan queue:work --queue=high,default

45 queue driver is also included which discards queued jobs.

[!NOTE] Laravel now offers Horizon, a beautiful dashboard and configuration system for your Redis powered queues. Check out the full Horizon documentation for more information.

Connections vs. Queues

Before getting started with Laravel queues, it is important to understand the distinction between "connections" and "queues". In your


php artisan queue:work --queue=high,default

44 configuration file, there is a


php artisan queue:work --queue=high,default

47 configuration array. This option defines the connections to backend queue services such as Amazon SQS, Beanstalk, or Redis. However, any given queue connection may have multiple "queues" which may be thought of as different stacks or piles of queued jobs.

Note that each connection configuration example in the


php artisan queue:work --queue=high,default

48 configuration file contains a


php artisan queue:work --queue=high,default

48 attribute. This is the default queue that jobs will be dispatched to when they are sent to a given connection. In other words, if you dispatch a job without explicitly defining which queue it should be dispatched to, the job will be placed on the queue that is defined in the


php artisan queue:work --queue=high,default

48 attribute of the connection configuration:


use App\Jobs\ProcessPodcast;

// This job is sent to the default connection's default queue...

ProcessPodcast::dispatch();

// This job is sent to the default connection's "emails" queue...

ProcessPodcast::dispatch()->onQueue('emails');

Some applications may not need to ever push jobs onto multiple queues, instead preferring to have one simple queue. However, pushing jobs to multiple queues can be especially useful for applications that wish to prioritize or segment how jobs are processed, since the Laravel queue worker allows you to specify which queues it should process by priority. For example, if you push jobs to a


php artisan queue:work --queue=high,default

51 queue, you may run a worker that gives them higher processing priority:


php artisan queue:work --queue=high,default

Driver Notes and Prerequisites

Database

In order to use the


php artisan queue:work --queue=high,default

52 queue driver, you will need a database table to hold the jobs. Typically, this is included in Laravel's default


php artisan queue:work --queue=high,default

53 database migration; however, if your application does not contain this migration, you may use the


php artisan queue:work --queue=high,default

54 Artisan command to create it:


php artisan make:queue-table

php artisan migrate

Redis

In order to use the


php artisan queue:work --queue=high,default

55 queue driver, you should configure a Redis database connection in your


php artisan queue:work --queue=high,default

56 configuration file.

[!WARNING]

The

php artisan queue:work --queue=high,default

57 and

php artisan queue:work --queue=high,default

58 Redis options are not supported by the

php artisan queue:work --queue=high,default

55 queue driver.

Redis Cluster

If your Redis queue connection uses a Redis Cluster, your queue names must contain a . This is required in order to ensure all of the Redis keys for a given queue are placed into the same hash slot:


'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', '{default}'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => null,

    'after_commit' => false,

],

Blocking

When using the Redis queue, you may use the


php artisan queue:work --queue=high,default

60 configuration option to specify how long the driver should wait for a job to become available before iterating through the worker loop and re-polling the Redis database.

Adjusting this value based on your queue load can be more efficient than continually polling the Redis database for new jobs. For instance, you may set the value to


php artisan queue:work --queue=high,default

61 to indicate that the driver should block for five seconds while waiting for a job to become available:


'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

],

[!WARNING]

Setting

php artisan queue:work --queue=high,default

60 to

php artisan queue:work --queue=high,default

63 will cause queue workers to block indefinitely until a job is available. This will also prevent signals such as

php artisan queue:work --queue=high,default

64 from being handled until the next job has been processed.

Other Driver Prerequisites

The following dependencies are needed for the listed queue drivers. These dependencies may be installed via the Composer package manager:

  • Amazon SQS:

    php artisan queue:work --queue=high,default

    65
  • Beanstalkd:

    php artisan queue:work --queue=high,default

    66
  • Redis:

    php artisan queue:work --queue=high,default

    67 or phpredis PHP extension

Creating Jobs

Generating Job Classes

By default, all of the queueable jobs for your application are stored in the


php artisan queue:work --queue=high,default

68 directory. If the


php artisan queue:work --queue=high,default

68 directory doesn't exist, it will be created when you run the


php artisan queue:work --queue=high,default

70 Artisan command:


php artisan make:job ProcessPodcast

The generated class will implement the


php artisan queue:work --queue=high,default

71 interface, indicating to Laravel that the job should be pushed onto the queue to run asynchronously.

[!NOTE] Job stubs may be customized using .

Class Structure

Job classes are very simple, normally containing only a


php artisan queue:work --queue=high,default

72 method that is invoked when the job is processed by the queue. To get started, let's take a look at an example job class. In this example, we'll pretend we manage a podcast publishing service and need to process the uploaded podcast files before they are published:


  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    In this example, note that we were able to pass an Eloquent model directly into the queued job's constructor. Because of the

    
    php artisan queue:work --queue=high,default
    
    

    73 trait that the job is using, Eloquent models and their loaded relationships will be gracefully serialized and unserialized when the job is processing.

    If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance and its loaded relationships from the database. This approach to model serialization allows for much smaller job payloads to be sent to your queue driver.

    
    php artisan queue:work --queue=high,default
    
    

    72 Method Dependency Injection

    The

    
    php artisan queue:work --queue=high,default
    
    

    72 method is invoked when the job is processed by the queue. Note that we are able to type-hint dependencies on the

    
    php artisan queue:work --queue=high,default
    
    

    72 method of the job. The Laravel service container automatically injects these dependencies.

    If you would like to take total control over how the container injects dependencies into the

    
    php artisan queue:work --queue=high,default
    
    

    72 method, you may use the container's

    
    php artisan queue:work --queue=high,default
    
    

    78 method. The

    
    php artisan queue:work --queue=high,default
    
    

    78 method accepts a callback which receives the job and the container. Within the callback, you are free to invoke the

    
    php artisan queue:work --queue=high,default
    
    

    72 method however you wish. Typically, you should call this method from the

    
    php artisan queue:work --queue=high,default
    
    

    81 method of your

    
    php artisan queue:work --queue=high,default
    
    

    82 service provider:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    [!WARNING]

    Binary data, such as raw image contents, should be passed through the

    php artisan queue:work --queue=high,default

    83 function before being passed to a queued job. Otherwise, the job may not properly serialize to JSON when being placed on the queue.

    Queued Relationships

    Because all loaded Eloquent model relationships also get serialized when a job is queued, the serialized job string can sometimes become quite large. Furthermore, when a job is deserialized and model relationships are re-retrieved from the database, they will be retrieved in their entirety. Any previous relationship constraints that were applied before the model was serialized during the job queueing process will not be applied when the job is deserialized. Therefore, if you wish to work with a subset of a given relationship, you should re-constrain that relationship within your queued job.

    Or, to prevent relations from being serialized, you can call the

    
    php artisan queue:work --queue=high,default
    
    

    84 method on the model when setting a property value. This method will return an instance of the model without its loaded relationships:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    If you are using PHP constructor property promotion and would like to indicate that an Eloquent model should not have its relations serialized, you may use the

    
    php artisan queue:work --queue=high,default
    
    

    85 attribute:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    If a job receives a collection or array of Eloquent models instead of a single model, the models within that collection will not have their relationships restored when the job is deserialized and executed. This is to prevent excessive resource usage on jobs that deal with large numbers of models.

    Unique Jobs

    [!WARNING]

    Unique jobs require a cache driver that supports . Currently, the

    php artisan queue:work --queue=high,default

    86,

    php artisan queue:work --queue=high,default

    55,

    php artisan queue:work --queue=high,default

    88,

    php artisan queue:work --queue=high,default

    52,

    php artisan queue:work --queue=high,default

    90, and

    php artisan queue:work --queue=high,default

    91 cache drivers support atomic locks. In addition, unique job constraints do not apply to jobs within batches.

    Sometimes, you may want to ensure that only one instance of a specific job is on the queue at any point in time. You may do so by implementing the

    
    php artisan queue:work --queue=high,default
    
    

    92 interface on your job class. This interface does not require you to define any additional methods on your class:

    
    php artisan queue:work --queue=high,default
    
    

    0

    In the example above, the

    
    php artisan queue:work --queue=high,default
    
    

    93 job is unique. So, the job will not be dispatched if another instance of the job is already on the queue and has not finished processing.

    In certain cases, you may want to define a specific "key" that makes the job unique or you may want to specify a timeout beyond which the job no longer stays unique. To accomplish this, you may define

    
    php artisan queue:work --queue=high,default
    
    

    94 and

    
    php artisan queue:work --queue=high,default
    
    

    95 properties or methods on your job class:

    
    php artisan queue:work --queue=high,default
    
    

    1

    In the example above, the

    
    php artisan queue:work --queue=high,default
    
    

    93 job is unique by a product ID. So, any new dispatches of the job with the same product ID will be ignored until the existing job has completed processing. In addition, if the existing job is not processed within one hour, the unique lock will be released and another job with the same unique key can be dispatched to the queue.

    [!WARNING] If your application dispatches jobs from multiple web servers or containers, you should ensure that all of your servers are communicating with the same central cache server so that Laravel can accurately determine if a job is unique.

    Keeping Jobs Unique Until Processing Begins

    By default, unique jobs are "unlocked" after a job completes processing or fails all of its retry attempts. However, there may be situations where you would like your job to unlock immediately before it is processed. To accomplish this, your job should implement the

    
    php artisan queue:work --queue=high,default
    
    

    97 contract instead of the

    
    php artisan queue:work --queue=high,default
    
    

    92 contract:

    
    php artisan queue:work --queue=high,default
    
    

    2

    Unique Job Locks

    Behind the scenes, when a

    
    php artisan queue:work --queue=high,default
    
    

    92 job is dispatched, Laravel attempts to acquire a with the

    
    php artisan queue:work --queue=high,default
    
    

    94 key. If the lock is not acquired, the job is not dispatched. This lock is released when the job completes processing or fails all of its retry attempts. By default, Laravel will use the default cache driver to obtain this lock. However, if you wish to use another driver for acquiring the lock, you may define a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    01 method that returns the cache driver that should be used:

    
    php artisan queue:work --queue=high,default
    
    

    3

    [!NOTE] If you only need to limit the concurrent processing of a job, use the job middleware instead.

    Encrypted Jobs

    Laravel allows you to ensure the privacy and integrity of a job's data via encryption. To get started, simply add the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    03 interface to the job class. Once this interface has been added to the class, Laravel will automatically encrypt your job before pushing it onto a queue:

    
    php artisan queue:work --queue=high,default
    
    

    4

    Job Middleware

    Job middleware allow you to wrap custom logic around the execution of queued jobs, reducing boilerplate in the jobs themselves. For example, consider the following

    
    php artisan queue:work --queue=high,default
    
    

    72 method which leverages Laravel's Redis rate limiting features to allow only one job to process every five seconds:

    
    php artisan queue:work --queue=high,default
    
    

    5

    While this code is valid, the implementation of the

    
    php artisan queue:work --queue=high,default
    
    

    72 method becomes noisy since it is cluttered with Redis rate limiting logic. In addition, this rate limiting logic must be duplicated for any other jobs that we want to rate limit.

    Instead of rate limiting in the handle method, we could define a job middleware that handles rate limiting. Laravel does not have a default location for job middleware, so you are welcome to place job middleware anywhere in your application. In this example, we will place the middleware in an

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    06 directory:

    
    php artisan queue:work --queue=high,default
    
    

    6

    As you can see, like route middleware, job middleware receive the job being processed and a callback that should be invoked to continue processing the job.

    After creating job middleware, they may be attached to a job by returning them from the job's

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    07 method. This method does not exist on jobs scaffolded by the

    
    php artisan queue:work --queue=high,default
    
    

    70 Artisan command, so you will need to manually add it to your job class:

    
    php artisan queue:work --queue=high,default
    
    

    7

    [!NOTE] Job middleware can also be assigned to queueable event listeners, mailables, and notifications.

    Rate Limiting

    Although we just demonstrated how to write your own rate limiting job middleware, Laravel actually includes a rate limiting middleware that you may utilize to rate limit jobs. Like , job rate limiters are defined using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    09 facade's

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    10 method.

    For example, you may wish to allow users to backup their data once per hour while imposing no such limit on premium customers. To accomplish this, you may define a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    09 in the

    
    php artisan queue:work --queue=high,default
    
    

    81 method of your

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    13:

    
    php artisan queue:work --queue=high,default
    
    

    8

    In the example above, we defined an hourly rate limit; however, you may easily define a rate limit based on minutes using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    14 method. In addition, you may pass any value you wish to the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    15 method of the rate limit; however, this value is most often used to segment rate limits by customer:

    
    php artisan queue:work --queue=high,default
    
    

    9

    Once you have defined your rate limit, you may attach the rate limiter to your job using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    16 middleware. Each time the job exceeds the rate limit, this middleware will release the job back to the queue with an appropriate delay based on the rate limit duration.

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    0

    Releasing a rate limited job back onto the queue will still increment the job's total number of

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    17. You may wish to tune your

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    18 and

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    19 properties on your job class accordingly. Or, you may wish to use the to define the amount of time until the job should no longer be attempted.

    If you do not want a job to be retried when it is rate limited, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    21 method:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    1

    [!NOTE]

    If you are using Redis, you may use the

    php artisan make:queue-table

    php artisan migrate

    22 middleware, which is fine-tuned for Redis and more efficient than the basic rate limiting middleware.

    Preventing Job Overlaps

    Laravel includes an

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    23 middleware that allows you to prevent job overlaps based on an arbitrary key. This can be helpful when a queued job is modifying a resource that should only be modified by one job at a time.

    For example, let's imagine you have a queued job that updates a user's credit score and you want to prevent credit score update job overlaps for the same user ID. To accomplish this, you can return the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    02 middleware from your job's

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    07 method:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    2

    Any overlapping jobs of the same type will be released back to the queue. You may also specify the number of seconds that must elapse before the released job will be attempted again:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    3

    If you wish to immediately delete any overlapping jobs so that they will not be retried, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    21 method:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    4

    The

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    02 middleware is powered by Laravel's atomic lock feature. Sometimes, your job may unexpectedly fail or timeout in such a way that the lock is not released. Therefore, you may explicitly define a lock expiration time using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    28 method. For example, the example below will instruct Laravel to release the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    02 lock three minutes after the job has started processing:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    5

    [!WARNING]

    The

    php artisan make:queue-table

    php artisan migrate

    02 middleware requires a cache driver that supports . Currently, the

    php artisan queue:work --queue=high,default

    86,

    php artisan queue:work --queue=high,default

    55,

    php artisan queue:work --queue=high,default

    88,

    php artisan queue:work --queue=high,default

    52,

    php artisan queue:work --queue=high,default

    90, and

    php artisan queue:work --queue=high,default

    91 cache drivers support atomic locks.

    Sharing Lock Keys Across Job Classes

    By default, the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    02 middleware will only prevent overlapping jobs of the same class. So, although two different job classes may use the same lock key, they will not be prevented from overlapping. However, you can instruct Laravel to apply the key across job classes using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    38 method:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    6

    Throttling Exceptions

    Laravel includes a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    39 middleware that allows you to throttle exceptions. Once the job throws a given number of exceptions, all further attempts to execute the job are delayed until a specified time interval lapses. This middleware is particularly useful for jobs that interact with third-party services that are unstable.

    For example, let's imagine a queued job that interacts with a third-party API that begins throwing exceptions. To throttle exceptions, you can return the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    40 middleware from your job's

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    07 method. Typically, this middleware should be paired with a job that implements :

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    7

    The first constructor argument accepted by the middleware is the number of exceptions the job can throw before being throttled, while the second constructor argument is the number of minutes that should elapse before the job is attempted again once it has been throttled. In the code example above, if the job throws 10 exceptions within 5 minutes, we will wait 5 minutes before attempting the job again.

    When a job throws an exception but the exception threshold has not yet been reached, the job will typically be retried immediately. However, you may specify the number of minutes such a job should be delayed by calling the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    42 method when attaching the middleware to the job:

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    8

    Internally, this middleware uses Laravel's cache system to implement rate limiting, and the job's class name is utilized as the cache "key". You may override this key by calling the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    15 method when attaching the middleware to your job. This may be useful if you have multiple jobs interacting with the same third-party service and you would like them to share a common throttling "bucket":

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    9

    By default, this middleware will throttle every exception. You can modify this behaviour by invoking the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    44 method when attaching the middleware to your job. The exception will then only be throttled if closure provided to the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    44 method returns

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    0

    If you would like to have the throttled exceptions reported to your application's exception handler, you can do so by invoking the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    47 method when attaching the middleware to your job. Optionally, you may provide a closure to the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    47 method and the exception will only be reported if the given closure returns

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    1

    [!NOTE]

    If you are using Redis, you may use the

    php artisan make:queue-table

    php artisan migrate

    50 middleware, which is fine-tuned for Redis and more efficient than the basic exception throttling middleware.

    Dispatching Jobs

    Once you have written your job class, you may dispatch it using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    51 method on the job itself. The arguments passed to the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    51 method will be given to the job's constructor:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    2

    If you would like to conditionally dispatch a job, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    53 and

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    54 methods:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    3

    In new Laravel applications, the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    55 driver is the default queue driver. This driver executes jobs synchronously in the foreground of the current request, which is often convenient during local development. If you would like to actually begin queueing jobs for background processing, you may specify a different queue driver within your application's

    
    php artisan queue:work --queue=high,default
    
    

    44 configuration file.

    Delayed Dispatching

    If you would like to specify that a job should not be immediately available for processing by a queue worker, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    57 method when dispatching the job. For example, let's specify that a job should not be available for processing until 10 minutes after it has been dispatched:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    4

    [!WARNING] The Amazon SQS queue service has a maximum delay time of 15 minutes.

    Dispatching After the Response is Sent to the Browser

    Alternatively, the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    58 method delays dispatching a job until after the HTTP response is sent to the user's browser if your web server is using FastCGI. This will still allow the user to begin using the application even though a queued job is still executing. This should typically only be used for jobs that take about a second, such as sending an email. Since they are processed within the current HTTP request, jobs dispatched in this fashion do not require a queue worker to be running in order for them to be processed:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    5

    You may also

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    51 a closure and chain the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    60 method onto the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    51 helper to execute a closure after the HTTP response has been sent to the browser:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    6

    Synchronous Dispatching

    If you would like to dispatch a job immediately (synchronously), you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    62 method. When using this method, the job will not be queued and will be executed immediately within the current process:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    7

    Jobs & Database Transactions

    While it is perfectly fine to dispatch jobs within database transactions, you should take special care to ensure that your job will actually be able to execute successfully. When dispatching a job within a transaction, it is possible that the job will be processed by a worker before the parent transaction has committed. When this happens, any updates you have made to models or database records during the database transaction(s) may not yet be reflected in the database. In addition, any models or database records created within the transaction(s) may not exist in the database.

    Thankfully, Laravel provides several methods of working around this problem. First, you may set the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    63 connection option in your queue connection's configuration array:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    8

    When the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    63 option is

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46, you may dispatch jobs within database transactions; however, Laravel will wait until the open parent database transactions have been committed before actually dispatching the job. Of course, if no database transactions are currently open, the job will be dispatched immediately.

    If a transaction is rolled back due to an exception that occurs during the transaction, the jobs that were dispatched during that transaction will be discarded.

    [!NOTE]

    Setting the

    php artisan make:queue-table

    php artisan migrate

    63 configuration option to

    php artisan make:queue-table

    php artisan migrate

    46 will also cause any queued event listeners, mailables, notifications, and broadcast events to be dispatched after all open database transactions have been committed.

    Specifying Commit Dispatch Behavior Inline

    If you do not set the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    63 queue connection configuration option to

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46, you may still indicate that a specific job should be dispatched after all open database transactions have been committed. To accomplish this, you may chain the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    70 method onto your dispatch operation:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    9

    Likewise, if the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    63 configuration option is set to

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46, you may indicate that a specific job should be dispatched immediately without waiting for any open database transactions to commit:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    0

    Job Chaining

    Job chaining allows you to specify a list of queued jobs that should be run in sequence after the primary job has executed successfully. If one job in the sequence fails, the rest of the jobs will not be run. To execute a queued job chain, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    73 method provided by the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    74 facade. Laravel's command bus is a lower level component that queued job dispatching is built on top of:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    1

    In addition to chaining job class instances, you may also chain closures:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    2

    [!WARNING]

    Deleting jobs using the

    php artisan make:queue-table

    php artisan migrate

    75 method within the job will not prevent chained jobs from being processed. The chain will only stop executing if a job in the chain fails.

    Chain Connection and Queue

    If you would like to specify the connection and queue that should be used for the chained jobs, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    76 and

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    77 methods. These methods specify the queue connection and queue name that should be used unless the queued job is explicitly assigned a different connection / queue:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    3

    Adding Jobs to the Chain

    Occasionally, you may need to prepend or append a job to an existing job chain from within another job in that chain. You may accomplish this using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    78 and

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    79 methods:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    4

    Chain Failures

    When chaining jobs, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    80 method to specify a closure that should be invoked if a job within the chain fails. The given callback will receive the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    81 instance that caused the job failure:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    5

    [!WARNING]

    Since chain callbacks are serialized and executed at a later time by the Laravel queue, you should not use the

    php artisan make:queue-table

    php artisan migrate

    82 variable within chain callbacks.

    Customizing The Queue a Connection

    Dispatching to a Particular Queue

    By pushing jobs to different queues, you may "categorize" your queued jobs and even prioritize how many workers you assign to various queues. Keep in mind, this does not push jobs to different queue "connections" as defined by your queue configuration file, but only to specific queues within a single connection. To specify the queue, use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    77 method when dispatching the job:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    6

    Alternatively, you may specify the job's queue by calling the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    77 method within the job's constructor:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    7

    Dispatching to a Particular Connection

    If your application interacts with multiple queue connections, you may specify which connection to push a job to using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    76 method:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    8

    You may chain the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    76 and

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    77 methods together to specify the connection and the queue for a job:

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    9

    Alternatively, you may specify the job's connection by calling the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    76 method within the job's constructor:

    
    php artisan make:job ProcessPodcast
    
    

    0

    Specifying Max Job Attempts / Timeout Values

    Max Attempts

    If one of your queued jobs is encountering an error, you likely do not want it to keep retrying indefinitely. Therefore, Laravel provides various ways to specify how many times or for how long a job may be attempted.

    One approach to specifying the maximum number of times a job may be attempted is via the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    89 switch on the Artisan command line. This will apply to all jobs processed by the worker unless the job being processed specifies the number of times it may be attempted:

    
    php artisan make:job ProcessPodcast
    
    

    1

    If a job exceeds its maximum number of attempts, it will be considered a "failed" job. For more information on handling failed jobs, consult the . If

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    90 is provided to the

    
    php artisan queue:work --queue=high,default
    
    

    43 command, the job will be retried indefinitely.

    You may take a more granular approach by defining the maximum number of times a job may be attempted on the job class itself. If the maximum number of attempts is specified on the job, it will take precedence over the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    89 value provided on the command line:

    
    php artisan make:job ProcessPodcast
    
    

    2

    If you need dynamic control over a particular job's maximum attempts, you may define a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    18 method on the job:

    
    php artisan make:job ProcessPodcast
    
    

    3

    Time Based Attempts

    As an alternative to defining how many times a job may be attempted before it fails, you may define a time at which the job should no longer be attempted. This allows a job to be attempted any number of times within a given time frame. To define the time at which a job should no longer be attempted, add a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    20 method to your job class. This method should return a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    95 instance:

    
    php artisan make:job ProcessPodcast
    
    

    4

    [!NOTE]

    You may also define a

    php artisan make:queue-table

    php artisan migrate

    18 property or

    php artisan make:queue-table

    php artisan migrate

    20 method on your .

    Max Exceptions

    Sometimes you may wish to specify that a job may be attempted many times, but should fail if the retries are triggered by a given number of unhandled exceptions (as opposed to being released by the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    98 method directly). To accomplish this, you may define a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    19 property on your job class:

    
    php artisan make:job ProcessPodcast
    
    

    5

    In this example, the job is released for ten seconds if the application is unable to obtain a Redis lock and will continue to be retried up to 25 times. However, the job will fail if three unhandled exceptions are thrown by the job.

    Timeout

    Often, you know roughly how long you expect your queued jobs to take. For this reason, Laravel allows you to specify a "timeout" value. By default, the timeout value is 60 seconds. If a job is processing for longer than the number of seconds specified by the timeout value, the worker processing the job will exit with an error. Typically, the worker will be restarted automatically by a .

    The maximum number of seconds that jobs can run may be specified using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    00 switch on the Artisan command line:

    
    php artisan make:job ProcessPodcast
    
    

    6

    If the job exceeds its maximum attempts by continually timing out, it will be marked as failed.

    You may also define the maximum number of seconds a job should be allowed to run on the job class itself. If the timeout is specified on the job, it will take precedence over any timeout specified on the command line:

    
    php artisan make:job ProcessPodcast
    
    

    7

    Sometimes, IO blocking processes such as sockets or outgoing HTTP connections may not respect your specified timeout. Therefore, when using these features, you should always attempt to specify a timeout using their APIs as well. For example, when using Guzzle, you should always specify a connection and request timeout value.

    [!WARNING]

    The

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', '{default}'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => null,

    'after_commit' => false,

    ],

    01 PHP extension must be installed in order to specify job timeouts. In addition, a job's "timeout" value should always be less than its value. Otherwise, the job may be re-attempted before it has actually finished executing or timed out.

    Failing on Timeout

    If you would like to indicate that a job should be marked as on timeout, you may define the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    02 property on the job class:

    
    php artisan make:job ProcessPodcast
    
    

    8

    Error Handling

    If an exception is thrown while the job is being processed, the job will automatically be released back onto the queue so it may be attempted again. The job will continue to be released until it has been attempted the maximum number of times allowed by your application. The maximum number of attempts is defined by the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    89 switch used on the

    
    php artisan queue:work --queue=high,default
    
    

    43 Artisan command. Alternatively, the maximum number of attempts may be defined on the job class itself. More information on running the queue worker .

    Manually Releasing a Job

    Sometimes you may wish to manually release a job back onto the queue so that it can be attempted again at a later time. You may accomplish this by calling the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    98 method:

    
    php artisan make:job ProcessPodcast
    
    

    9

    By default, the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    98 method will release the job back onto the queue for immediate processing. However, you may instruct the queue to not make the job available for processing until a given number of seconds has elapsed by passing an integer or date instance to the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    98 method:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    0

    Manually Failing a Job

    Occasionally you may need to manually mark a job as "failed". To do so, you may call the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    08 method:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    1

    If you would like to mark your job as failed because of an exception that you have caught, you may pass the exception to the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    08 method. Or, for convenience, you may pass a string error message which will be converted to an exception for you:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    2

    [!NOTE] For more information on failed jobs, check out the .

    Job Batching

    Laravel's job batching feature allows you to easily execute a batch of jobs and then perform some action when the batch of jobs has completed executing. Before getting started, you should create a database migration to build a table which will contain meta information about your job batches, such as their completion percentage. This migration may be generated using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    10 Artisan command:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    3

    Defining Batchable Jobs

    To define a batchable job, you should as normal; however, you should add the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    11 trait to the job class. This trait provides access to a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    12 method which may be used to retrieve the current batch that the job is executing within:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    4

    Dispatching Batches

    To dispatch a batch of jobs, you should use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    12 method of the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    74 facade. Of course, batching is primarily useful when combined with completion callbacks. So, you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    15,

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    80, and

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    17 methods to define completion callbacks for the batch. Each of these callbacks will receive an

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    18 instance when they are invoked. In this example, we will imagine we are queueing a batch of jobs that each process a given number of rows from a CSV file:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    5

    The batch's ID, which may be accessed via the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    19 property, may be used to for information about the batch after it has been dispatched.

    [!WARNING]

    Since batch callbacks are serialized and executed at a later time by the Laravel queue, you should not use the

    php artisan make:queue-table

    php artisan migrate

    82 variable within the callbacks. In addition, since batched jobs are wrapped within database transactions, database statements that trigger implicit commits should not be executed within the jobs.

    Naming Batches

    Some tools such as Laravel Horizon and Laravel Telescope may provide more user-friendly debug information for batches if batches are named. To assign an arbitrary name to a batch, you may call the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    21 method while defining the batch:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    6

    Batch Connection and Queue

    If you would like to specify the connection and queue that should be used for the batched jobs, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    76 and

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    77 methods. All batched jobs must execute within the same connection and queue:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    7

    Chains and Batches

    You may define a set of within a batch by placing the chained jobs within an array. For example, we may execute two job chains in parallel and execute a callback when both job chains have finished processing:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    8

    Conversely, you may run batches of jobs within a by defining batches within the chain. For example, you could first run a batch of jobs to release multiple podcasts then a batch of jobs to send the release notifications:

    
    
  • Create a new job instance.
  • */ public function __construct( public Podcast $podcast, ) {} /**
    • Execute the job.
    */ public function handle(AudioProcessor $processor): void { // Process uploaded podcast... } }

    9

    Adding Jobs to Batches

    Sometimes it may be useful to add additional jobs to a batch from within a batched job. This pattern can be useful when you need to batch thousands of jobs which may take too long to dispatch during a web request. So, instead, you may wish to dispatch an initial batch of "loader" jobs that hydrate the batch with even more jobs:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    0

    In this example, we will use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    24 job to hydrate the batch with additional jobs. To accomplish this, we may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    25 method on the batch instance that may be accessed via the job's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    12 method:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    1

    [!WARNING] You may only add jobs to a batch from within a job that belongs to the same batch.

    Inspecting Batches

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    18 instance that is provided to batch completion callbacks has a variety of properties and methods to assist you in interacting with and inspecting a given batch of jobs:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    2

    Returning Batches From Routes

    All

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    18 instances are JSON serializable, meaning you can return them directly from one of your application's routes to retrieve a JSON payload containing information about the batch, including its completion progress. This makes it convenient to display information about the batch's completion progress in your application's UI.

    To retrieve a batch by its ID, you may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    74 facade's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    30 method:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    3

    Cancelling Batches

    Sometimes you may need to cancel a given batch's execution. This can be accomplished by calling the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    31 method on the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    18 instance:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    4

    As you may have noticed in the previous examples, batched jobs should typically determine if their corresponding batch has been cancelled before continuing execution. However, for convenience, you may assign the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    33 to the job instead. As its name indicates, this middleware will instruct Laravel to not process the job if its corresponding batch has been cancelled:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    5

    Batch Failures

    When a batched job fails, the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    80 callback (if assigned) will be invoked. This callback is only invoked for the first job that fails within the batch.

    Allowing Failures

    When a job within a batch fails, Laravel will automatically mark the batch as "cancelled". If you wish, you may disable this behavior so that a job failure does not automatically mark the batch as cancelled. This may be accomplished by calling the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    35 method while dispatching the batch:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    6

    Retrying Failed Batch Jobs

    For convenience, Laravel provides a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    36 Artisan command that allows you to easily retry all of the failed jobs for a given batch. The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    36 command accepts the UUID of the batch whose failed jobs should be retried:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    7

    Pruning Batches

    Without pruning, the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    38 table can accumulate records very quickly. To mitigate this, you should schedule the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    39 Artisan command to run daily:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    8

    By default, all finished batches that are more than 24 hours old will be pruned. You may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    40 option when calling the command to determine how long to retain batch data. For example, the following command will delete all batches that finished over 48 hours ago:

    
    use App\Jobs\ProcessPodcast;
    
    use App\Services\AudioProcessor;
    
    use Illuminate\Contracts\Foundation\Application;
    
    $this->app->bindMethod([ProcessPodcast::class, 'handle'], function (ProcessPodcast $job, Application $app) {
    
        return $job->handle($app->make(AudioProcessor::class));
    
    });
    
    

    9

    Sometimes, your

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    41 table may accumulate batch records for batches that never completed successfully, such as batches where a job failed and that job was never retried successfully. You may instruct the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    39 command to prune these unfinished batch records using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    43 option:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    0

    Likewise, your

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    41 table may also accumulate batch records for cancelled batches. You may instruct the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    39 command to prune these cancelled batch records using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    46 option:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    1

    Storing Batches in DynamoDB

    Laravel also provides support for storing batch meta information in DynamoDB instead of a relational database. However, you will need to manually create a DynamoDB table to store all of the batch records.

    Typically, this table should be named

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    38, but you should name the table based on the value of the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    48 configuration value within your application's

    
    php artisan queue:work --queue=high,default
    
    

    48 configuration file.

    DynamoDB Batch Table Configuration

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    38 table should have a string primary partition key named

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    51 and a string primary sort key named

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    52. The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    51 portion of the key will contain your application's name as defined by the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    21 configuration value within your application's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    55 configuration file. Since the application name is part of the DynamoDB table's key, you can use the same table to store job batches for multiple Laravel applications.

    In addition, you may define

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    56 attribute for your table if you would like to take advantage of .

    DynamoDB Configuration

    Next, install the AWS SDK so that your Laravel application can communicate with Amazon DynamoDB:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    2

    Then, set the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    57 configuration option's value to

    
    php artisan queue:work --queue=high,default
    
    

    88. In addition, you should define

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    59,

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    60, and

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    61 configuration options within the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    62 configuration array. These options will be used to authenticate with AWS. When using the

    
    php artisan queue:work --queue=high,default
    
    

    88 driver, the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    64 configuration option is unnecessary:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    3

    Pruning Batches in DynamoDB

    When utilizing DynamoDB to store job batch information, the typical pruning commands used to prune batches stored in a relational database will not work. Instead, you may utilize DynamoDB's native TTL functionality to automatically remove records for old batches.

    If you defined your DynamoDB table with a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    56 attribute, you may define configuration parameters to instruct Laravel how to prune batch records. The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    66 configuration value defines the name of the attribute holding the TTL, while the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    67 configuration value defines the number of seconds after which a batch record can be removed from the DynamoDB table, relative to the last time the record was updated:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    4

    Queueing Closures

    Instead of dispatching a job class to the queue, you may also dispatch a closure. This is great for quick, simple tasks that need to be executed outside of the current request cycle. When dispatching closures to the queue, the closure's code content is cryptographically signed so that it can not be modified in transit:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    5

    Using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    80 method, you may provide a closure that should be executed if the queued closure fails to complete successfully after exhausting all of your queue's :

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    6

    [!WARNING]

    Since

    php artisan make:queue-table

    php artisan migrate

    80 callbacks are serialized and executed at a later time by the Laravel queue, you should not use the

    php artisan make:queue-table

    php artisan migrate

    82 variable within

    php artisan make:queue-table

    php artisan migrate

    80 callbacks.

    Running the Queue Worker

    The

    
    php artisan queue:work --queue=high,default
    
    

    43 Command

    Laravel includes an Artisan command that will start a queue worker and process new jobs as they are pushed onto the queue. You may run the worker using the

    
    php artisan queue:work --queue=high,default
    
    

    43 Artisan command. Note that once the

    
    php artisan queue:work --queue=high,default
    
    

    43 command has started, it will continue to run until it is manually stopped or you close your terminal:

    [!NOTE]

    To keep the

    php artisan queue:work --queue=high,default

    43 process running permanently in the background, you should use a process monitor such as to ensure that the queue worker does not stop running.

    You may include the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    76 flag when invoking the

    
    php artisan queue:work --queue=high,default
    
    

    43 command if you would like the processed job IDs to be included in the command's output:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    7

    Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to . In addition, remember that any static state created or modified by your application will not be automatically reset between jobs.

    Alternatively, you may run the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    78 command. When using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    78 command, you don't have to manually restart the worker when you want to reload your updated code or reset the application state; however, this command is significantly less efficient than the

    
    php artisan queue:work --queue=high,default
    
    

    43 command:

    Running Multiple Queue Workers

    To assign multiple workers to a queue and process jobs concurrently, you should simply start multiple

    
    php artisan queue:work --queue=high,default
    
    

    43 processes. This can either be done locally via multiple tabs in your terminal or in production using your process manager's configuration settings. , you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    82 configuration value.

    Specifying the Connection and Queue

    You may also specify which queue connection the worker should utilize. The connection name passed to the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    83 command should correspond to one of the connections defined in your

    
    php artisan queue:work --queue=high,default
    
    

    44 configuration file:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    8

    By default, the

    
    php artisan queue:work --queue=high,default
    
    

    43 command only processes jobs for the default queue on a given connection. However, you may customize your queue worker even further by only processing particular queues for a given connection. For example, if all of your emails are processed in an

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    86 queue on your

    
    php artisan queue:work --queue=high,default
    
    

    55 queue connection, you may issue the following command to start a worker that only processes that queue:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    9

    Processing a Specified Number of Jobs

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    88 option may be used to instruct the worker to only process a single job from the queue:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    0

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    89 option may be used to instruct the worker to process the given number of jobs and then exit. This option may be useful when combined with so that your workers are automatically restarted after processing a given number of jobs, releasing any memory they may have accumulated:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    1

    Processing All Queued Jobs and Then Exiting

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    90 option may be used to instruct the worker to process all jobs and then exit gracefully. This option can be useful when processing Laravel queues within a Docker container if you wish to shutdown the container after the queue is empty:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    2

    Processing Jobs for a Given Number of Seconds

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    91 option may be used to instruct the worker to process jobs for the given number of seconds and then exit. This option may be useful when combined with so that your workers are automatically restarted after processing jobs for a given amount of time, releasing any memory they may have accumulated:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    3

    Worker Sleep Duration

    When jobs are available on the queue, the worker will keep processing jobs with no delay in between jobs. However, the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    92 option determines how many seconds the worker will "sleep" if there are no jobs available. Of course, while sleeping, the worker will not process any new jobs:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    4

    Maintenance Mode and Queues

    While your application is in , no queued jobs will be handled. The jobs will continue to be handled as normal once the application is out of maintenance mode.

    To force your queue workers to process jobs even if maintenance mode is enabled, you may use

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    93 option:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    5

    Resource Considerations

    Daemon queue workers do not "reboot" the framework before processing each job. Therefore, you should release any heavy resources after each job completes. For example, if you are doing image manipulation with the GD library, you should free the memory with

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    94 when you are done processing the image.

    Queue Priorities

    Sometimes you may wish to prioritize how your queues are processed. For example, in your

    
    php artisan queue:work --queue=high,default
    
    

    44 configuration file, you may set the default

    
    php artisan queue:work --queue=high,default
    
    

    48 for your

    
    php artisan queue:work --queue=high,default
    
    

    55 connection to

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    98. However, occasionally you may wish to push a job to a

    
    php artisan queue:work --queue=high,default
    
    

    51 priority queue like so:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    6

    To start a worker that verifies that all of the

    
    php artisan queue:work --queue=high,default
    
    

    51 queue jobs are processed before continuing to any jobs on the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    98 queue, pass a comma-delimited list of queue names to the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    83 command:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    7

    Queue Workers and Deployment

    Since queue workers are long-lived processes, they will not notice changes to your code without being restarted. So, the simplest way to deploy an application using queue workers is to restart the workers during your deployment process. You may gracefully restart all of the workers by issuing the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    03 command:

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    8

    This command will instruct all queue workers to gracefully exit after they finish processing their current job so that no existing jobs are lost. Since the queue workers will exit when the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    03 command is executed, you should be running a process manager such as to automatically restart the queue workers.

    [!NOTE] The queue uses the cache to store restart signals, so you should verify that a cache driver is properly configured for your application before using this feature.

    Job Expirations and Timeouts

    Job Expiration

    In your

    
    php artisan queue:work --queue=high,default
    
    

    44 configuration file, each queue connection defines a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    06 option. This option specifies how many seconds the queue connection should wait before retrying a job that is being processed. For example, if the value of

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    06 is set to

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    08, the job will be released back onto the queue if it has been processing for 90 seconds without being released or deleted. Typically, you should set the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    06 value to the maximum number of seconds your jobs should reasonably take to complete processing.

    [!WARNING]

    The only queue connection which does not contain a

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    06 value is Amazon SQS. SQS will retry the job based on the Default Visibility Timeout which is managed within the AWS console.

    Worker Timeouts

    The

    
    php artisan queue:work --queue=high,default
    
    

    43 Artisan command exposes a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    00 option. By default, the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    00 value is 60 seconds. If a job is processing for longer than the number of seconds specified by the timeout value, the worker processing the job will exit with an error. Typically, the worker will be restarted automatically by a :

    
    use Illuminate\Queue\Attributes\WithoutRelations;
    
    /**
    
    
    • Create a new job instance.
    */ public function __construct( #[WithoutRelations] public Podcast $podcast ) { }

    9

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    06 configuration option and the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    00 CLI option are different, but work together to ensure that jobs are not lost and that jobs are only successfully processed once.

    [!WARNING]

    The

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', '{default}'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => null,

    'after_commit' => false,

    ],

    00 value should always be at least several seconds shorter than your

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    06 configuration value. This will ensure that a worker processing a frozen job is always terminated before the job is retried. If your

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', '{default}'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => null,

    'after_commit' => false,

    ],

    00 option is longer than your

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    06 configuration value, your jobs may be processed twice.

    Supervisor Configuration

    In production, you need a way to keep your

    
    php artisan queue:work --queue=high,default
    
    

    43 processes running. A

    
    php artisan queue:work --queue=high,default
    
    

    43 process may stop running for a variety of reasons, such as an exceeded worker timeout or the execution of the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    03 command.

    For this reason, you need to configure a process monitor that can detect when your

    
    php artisan queue:work --queue=high,default
    
    

    43 processes exit and automatically restart them. In addition, process monitors can allow you to specify how many

    
    php artisan queue:work --queue=high,default
    
    

    43 processes you would like to run concurrently. Supervisor is a process monitor commonly used in Linux environments and we will discuss how to configure it in the following documentation.

    Installing Supervisor

    Supervisor is a process monitor for the Linux operating system, and will automatically restart your

    
    php artisan queue:work --queue=high,default
    
    

    43 processes if they fail. To install Supervisor on Ubuntu, you may use the following command:

    
    php artisan queue:work --queue=high,default
    
    

    00

    [!NOTE] If configuring and managing Supervisor yourself sounds overwhelming, consider using Laravel Forge, which will automatically install and configure Supervisor for your production Laravel projects.

    Configuring Supervisor

    Supervisor configuration files are typically stored in the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    26 directory. Within this directory, you may create any number of configuration files that instruct supervisor how your processes should be monitored. For example, let's create a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    27 file that starts and monitors

    
    php artisan queue:work --queue=high,default
    
    

    43 processes:

    
    php artisan queue:work --queue=high,default
    
    

    01

    In this example, the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    82 directive will instruct Supervisor to run eight

    
    php artisan queue:work --queue=high,default
    
    

    43 processes and monitor all of them, automatically restarting them if they fail. You should change the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    31 directive of the configuration to reflect your desired queue connection and worker options.

    [!WARNING]

    You should ensure that the value of

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    32 is greater than the number of seconds consumed by your longest running job. Otherwise, Supervisor may kill the job before it is finished processing.

    Starting Supervisor

    Once the configuration file has been created, you may update the Supervisor configuration and start the processes using the following commands:

    
    php artisan queue:work --queue=high,default
    
    

    02

    For more information on Supervisor, consult the Supervisor documentation.

    Dealing With Failed Jobs

    Sometimes your queued jobs will fail. Don't worry, things don't always go as planned! Laravel includes a convenient way to . After an asynchronous job has exceeded this number of attempts, it will be inserted into the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33 database table. that fail are not stored in this table and their exceptions are immediately handled by the application.

    A migration to create the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33 table is typically already present in new Laravel applications. However, if your application does not contain a migration for this table, you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    35 command to create the migration:

    
    php artisan queue:work --queue=high,default
    
    

    03

    When running a process, you may specify the maximum number of times a job should be attempted using the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    89 switch on the

    
    php artisan queue:work --queue=high,default
    
    

    43 command. If you do not specify a value for the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    89 option, jobs will only be attempted once or as many times as specified by the job class'

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    39 property:

    
    php artisan queue:work --queue=high,default
    
    

    04

    Using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    40 option, you may specify how many seconds Laravel should wait before retrying a job that has encountered an exception. By default, a job is immediately released back onto the queue so that it may be attempted again:

    
    php artisan queue:work --queue=high,default
    
    

    05

    If you would like to configure how many seconds Laravel should wait before retrying a job that has encountered an exception on a per-job basis, you may do so by defining a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    42 property on your job class:

    
    php artisan queue:work --queue=high,default
    
    

    06

    If you require more complex logic for determining the job's backoff time, you may define a

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    42 method on your job class:

    
    php artisan queue:work --queue=high,default
    
    

    07

    You may easily configure "exponential" backoffs by returning an array of backoff values from the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    42 method. In this example, the retry delay will be 1 second for the first retry, 5 seconds for the second retry, 10 seconds for the third retry, and 10 seconds for every subsequent retry if there are more attempts remaining:

    
    php artisan queue:work --queue=high,default
    
    

    08

    Cleaning Up After Failed Jobs

    When a particular job fails, you may want to send an alert to your users or revert any actions that were partially completed by the job. To accomplish this, you may define a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    44 method on your job class. The

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    81 instance that caused the job to fail will be passed to the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    44 method:

    
    php artisan queue:work --queue=high,default
    
    

    09

    [!WARNING]

    A new instance of the job is instantiated before invoking the

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    44 method; therefore, any class property modifications that may have occurred within the

    php artisan queue:work --queue=high,default

    72 method will be lost.

    Retrying Failed Jobs

    To view all of the failed jobs that have been inserted into your

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33 database table, you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    50 Artisan command:

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    50 command will list the job ID, connection, queue, failure time, and other information about the job. The job ID may be used to retry the failed job. For instance, to retry a failed job that has an ID of

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    52, issue the following command:

    
    php artisan queue:work --queue=high,default
    
    

    10

    If necessary, you may pass multiple IDs to the command:

    
    php artisan queue:work --queue=high,default
    
    

    11

    You may also retry all of the failed jobs for a particular queue:

    
    php artisan queue:work --queue=high,default
    
    

    12

    To retry all of your failed jobs, execute the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    53 command and pass

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    54 as the ID:

    
    php artisan queue:work --queue=high,default
    
    

    13

    If you would like to delete a failed job, you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    55 command:

    
    php artisan queue:work --queue=high,default
    
    

    14

    [!NOTE]

    When using Horizon, you should use the

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    56 command to delete a failed job instead of the

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    55 command.

    To delete all of your failed jobs from the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33 table, you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    59 command:

    Ignoring Missing Models

    When injecting an Eloquent model into a job, the model is automatically serialized before being placed on the queue and re-retrieved from the database when the job is processed. However, if the model has been deleted while the job was waiting to be processed by a worker, your job may fail with a

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    60.

    For convenience, you may choose to automatically delete jobs with missing models by setting your job's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    61 property to

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46. When this property is set to

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    46, Laravel will quietly discard the job without raising an exception:

    
    php artisan queue:work --queue=high,default
    
    

    15

    Pruning Failed Jobs

    You may prune the records in your application's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33 table by invoking the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    65 Artisan command:

    
    php artisan queue:work --queue=high,default
    
    

    16

    By default, all the failed job records that are more than 24 hours old will be pruned. If you provide the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    66 option to the command, only the failed job records that were inserted within the last N number of hours will be retained. For example, the following command will delete all the failed job records that were inserted more than 48 hours ago:

    
    php artisan queue:work --queue=high,default
    
    

    17

    Storing Failed Jobs in DynamoDB

    Laravel also provides support for storing your failed job records in DynamoDB instead of a relational database table. However, you must manually create a DynamoDB table to store all of the failed job records. Typically, this table should be named

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33, but you should name the table based on the value of the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    68 configuration value within your application's

    
    php artisan queue:work --queue=high,default
    
    

    48 configuration file.

    The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    33 table should have a string primary partition key named

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    51 and a string primary sort key named

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    72. The

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    51 portion of the key will contain your application's name as defined by the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    21 configuration value within your application's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    55 configuration file. Since the application name is part of the DynamoDB table's key, you can use the same table to store failed jobs for multiple Laravel applications.

    In addition, ensure that you install the AWS SDK so that your Laravel application can communicate with Amazon DynamoDB:

    
    /**
    
    
    • Create a new job instance.
    */ public function __construct(Podcast $podcast) { $this->podcast = $podcast->withoutRelations(); }

    2

    Next, set the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    76 configuration option's value to

    
    php artisan queue:work --queue=high,default
    
    

    88. In addition, you should define

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    59,

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    60, and

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', '{default}'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => null,
    
        'after_commit' => false,
    
    ],
    
    

    61 configuration options within the failed job configuration array. These options will be used to authenticate with AWS. When using the

    
    php artisan queue:work --queue=high,default
    
    

    88 driver, the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    82 configuration option is unnecessary:

    
    php artisan queue:work --queue=high,default
    
    

    19

    Disabling Failed Job Storage

    You may instruct Laravel to discard failed jobs without storing them by setting the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    76 configuration option's value to

    
    php artisan queue:work --queue=high,default
    
    

    45. Typically, this may be accomplished via the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    85 environment variable:

    Failed Job Events

    If you would like to register an event listener that will be invoked when a job fails, you may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    86 facade's

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    87 method. For example, we may attach a closure to this event from the

    
    php artisan queue:work --queue=high,default
    
    

    81 method of the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    13 that is included with Laravel:

    
    php artisan queue:work --queue=high,default
    
    

    20

    Clearing Jobs From Queues

    [!NOTE]

    When using Horizon, you should use the

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    90 command to clear jobs from the queue instead of the

    'redis' => [

    'driver' => 'redis',

    'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),

    'queue' => env('REDIS_QUEUE', 'default'),

    'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),

    'block_for' => 5,

    'after_commit' => false,

    ],

    91 command.

    If you would like to delete all jobs from the default queue of the default connection, you may do so using the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    91 Artisan command:

    You may also provide the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    93 argument and

    
    php artisan queue:work --queue=high,default
    
    

    48 option to delete jobs from a specific connection and queue:

    
    php artisan queue:work --queue=high,default
    
    

    21

    [!WARNING] Clearing jobs from queues is only available for the SQS, Redis, and database queue drivers. In addition, the SQS message deletion process takes up to 60 seconds, so jobs sent to the SQS queue up to 60 seconds after you clear the queue might also be deleted.

    Monitoring Your Queues

    If your queue receives a sudden influx of jobs, it could become overwhelmed, leading to a long wait time for jobs to complete. If you wish, Laravel can alert you when your queue job count exceeds a specified threshold.

    To get started, you should schedule the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    95 command to run every minute. The command accepts the names of the queues you wish to monitor as well as your desired job count threshold:

    
    php artisan queue:work --queue=high,default
    
    

    22

    Scheduling this command alone is not enough to trigger a notification alerting you of the queue's overwhelmed status. When the command encounters a queue that has a job count exceeding your threshold, an

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    96 event will be dispatched. You may listen for this event within your application's

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    13 in order to send a notification to you or your development team:

    
    php artisan queue:work --queue=high,default
    
    

    23

    Testing

    When testing code that dispatches jobs, you may wish to instruct Laravel to not actually execute the job itself, since the job's code can be tested directly and separately of the code that dispatches it. Of course, to test the job itself, you may instantiate a job instance and invoke the

    
    php artisan queue:work --queue=high,default
    
    

    72 method directly in your test.

    You may use the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    86 facade's

    
    php artisan make:job ProcessPodcast
    
    

    00 method to prevent queued jobs from actually being pushed to the queue. After calling the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    86 facade's

    
    php artisan make:job ProcessPodcast
    
    

    00 method, you may then assert that the application attempted to push jobs to the queue:

    
    php artisan queue:work --queue=high,default
    
    

    24

    
    php artisan queue:work --queue=high,default
    
    

    25

    You may pass a closure to the

    
    php artisan make:job ProcessPodcast
    
    

    03 or

    
    php artisan make:job ProcessPodcast
    
    

    04 methods in order to assert that a job was pushed that passes a given "truth test". If at least one job was pushed that passes the given truth test then the assertion will be successful:

    
    php artisan queue:work --queue=high,default
    
    

    26

    Faking a Subset of Jobs

    If you only need to fake specific jobs while allowing your other jobs to execute normally, you may pass the class names of the jobs that should be faked to the

    
    php artisan make:job ProcessPodcast
    
    

    00 method:

    
    php artisan queue:work --queue=high,default
    
    

    27

    
    php artisan queue:work --queue=high,default
    
    

    28

    You may fake all jobs except for a set of specified jobs using the

    
    php artisan make:job ProcessPodcast
    
    

    06 method:

    
    php artisan queue:work --queue=high,default
    
    

    29

    Testing Job Chains

    To test job chains, you will need to utilize the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    74 facade's faking capabilities. The

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    74 facade's

    
    php artisan make:job ProcessPodcast
    
    

    09 method may be used to assert that a was dispatched. The

    
    php artisan make:job ProcessPodcast
    
    

    09 method accepts an array of chained jobs as its first argument:

    
    php artisan queue:work --queue=high,default
    
    

    30

    As you can see in the example above, the array of chained jobs may be an array of the job's class names. However, you may also provide an array of actual job instances. When doing so, Laravel will ensure that the job instances are of the same class and have the same property values of the chained jobs dispatched by your application:

    
    php artisan queue:work --queue=high,default
    
    

    31

    You may use the

    
    php artisan make:job ProcessPodcast
    
    

    11 method to assert that a job was pushed without a chain of jobs:

    
    php artisan queue:work --queue=high,default
    
    

    32

    Testing Chain Modifications

    If a chained job , you may use the job's

    
    php artisan make:job ProcessPodcast
    
    

    12 method to assert that the job has the expected chain of remaining jobs:

    
    php artisan queue:work --queue=high,default
    
    

    33

    The

    
    php artisan make:job ProcessPodcast
    
    

    13 method may be used to assert that the job's remaining chain is empty:

    
    php artisan queue:work --queue=high,default
    
    

    34

    Testing Chained Batches

    If your job chain , you may assert that the chained batch matches your expectations by inserting a

    
    php artisan make:job ProcessPodcast
    
    

    14 definition within your chain assertion:

    
    php artisan queue:work --queue=high,default
    
    

    35

    Testing Job Batches

    The

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    74 facade's

    
    php artisan make:job ProcessPodcast
    
    

    16 method may be used to assert that a was dispatched. The closure given to the

    
    php artisan make:job ProcessPodcast
    
    

    16 method receives an instance of

    
    php artisan make:job ProcessPodcast
    
    

    18, which may be used to inspect the jobs within the batch:

    
    php artisan queue:work --queue=high,default
    
    

    36

    You may use the

    
    php artisan make:job ProcessPodcast
    
    

    19 method to assert that a given number of batches were dispatched:

    
    php artisan queue:work --queue=high,default
    
    

    37

    You may use

    
    php artisan make:job ProcessPodcast
    
    

    20 to assert that no batches were dispatched:

    
    php artisan queue:work --queue=high,default
    
    

    38

    Testing Job / Batch Interaction

    In addition, you may occasionally need to test an individual job's interaction with its underlying batch. For example, you may need to test if a job cancelled further processing for its batch. To accomplish this, you need to assign a fake batch to the job via the

    
    php artisan make:job ProcessPodcast
    
    

    21 method. The

    
    php artisan make:job ProcessPodcast
    
    

    21 method returns a tuple containing the job instance and the fake batch:

    
    php artisan queue:work --queue=high,default
    
    

    39

    Testing Job / Queue Interactions

    Sometimes, you may need to test that a queued job . Or, you may need to test that the job deleted itself. You may test these queue interactions by instantiating the job and invoking the

    
    php artisan make:job ProcessPodcast
    
    

    23 method.

    Once the job's queue interactions have been faked, you may invoke the

    
    php artisan queue:work --queue=high,default
    
    

    72 method on the job. After invoking the job, the

    
    php artisan make:job ProcessPodcast
    
    

    25,

    
    php artisan make:job ProcessPodcast
    
    

    26, and

    
    php artisan make:job ProcessPodcast
    
    

    27 methods may be used to make assertions against the job's queue interactions:

    
    php artisan queue:work --queue=high,default
    
    

    40

    Job Events

    Using the

    
    php artisan make:job ProcessPodcast
    
    

    28 and

    
    php artisan make:job ProcessPodcast
    
    

    29 methods on the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    86 facade, you may specify callbacks to be executed before or after a queued job is processed. These callbacks are a great opportunity to perform additional logging or increment statistics for a dashboard. Typically, you should call these methods from the

    
    php artisan queue:work --queue=high,default
    
    

    81 method of a service provider. For example, we may use the

    
    php artisan make:queue-table
    
    php artisan migrate
    
    

    13 that is included with Laravel:

    
    php artisan queue:work --queue=high,default
    
    

    41

    Using the

    
    php artisan make:job ProcessPodcast
    
    

    33 method on the

    
    'redis' => [
    
        'driver' => 'redis',
    
        'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
    
        'queue' => env('REDIS_QUEUE', 'default'),
    
        'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
    
        'block_for' => 5,
    
        'after_commit' => false,
    
    ],
    
    

    86 facade, you may specify callbacks that execute before the worker attempts to fetch a job from a queue. For example, you might register a closure to rollback any transactions that were left open by a previously failed job: