---
title: 'Queues in Laravel: Main Things You Need to Know (Two Examples)'
source: 'https://youtube.com/watch?v=D5tr7r2_i7E'
video_id: 'D5tr7r2_i7E'
date: 2026-06-16
duration_sec: 0
---

# Queues in Laravel: Main Things You Need to Know (Two Examples)

> Source: [Queues in Laravel: Main Things You Need to Know (Two Examples)](https://youtube.com/watch?v=D5tr7r2_i7E)

## Summary

This video explains the core concepts of Laravel Queues, demonstrating how to offload time-consuming tasks like sending email notifications and generating PDF invoices to the background. It covers making notifications queuable, creating custom job classes, handling job failures, and setting up queues in production with Redis, Horizon, and Supervisor.

### Key Points

- **When to Use Queues** [0:52] — Queues are used when you don't want users to wait for tasks like sending emails, generating reports, or processing uploaded files. The success message is shown immediately, and the job runs in the background.
- **Example 1: Queuing Notifications** [1:33] — Without a queue, notifying 3 users took 4 seconds. With a queue, the response is immediate. Notifications can be made queuable by adding `implements ShouldQueue` and `use Queueable`.
- **Example 2: Custom Queue Job for PDF Invoice** [4:16] — Create a custom job with `php artisan make:job GenerateOrderInvoice`. The job implements `ShouldQueue` and `use Queueable`. Dispatch it from the controller with `GenerateOrderInvoice::dispatch($orderId)`. Re-query data inside the job to avoid stale data.
- **Handling Job Failures** [5:47] — If a job fails, the error is logged in `laravel.log` and the job is moved to the `failed_jobs` table. Retry with `php artisan queue:retry all`. After code changes, restart the queue worker.
- **Production Setup: Redis, Horizon, Supervisor** [8:36] — For production, use Redis as the queue driver, Laravel Horizon for monitoring, and Supervisor to keep workers running. Tools like Laravel Forge simplify setup.

## Transcript

Hello guys, today let's talk about
Laravel Q's. I will try to take this
very complex topic and explain the main
things that you need to know about Q's
in roughly 10 to 15 minutes. And this is
kind of a challenge I decided for
myself. Take some complex topic in
Laravel and try to explain it in 10 to
15 minutes. So you will see more of
these videos in the future. How did I go
with this simplification? Shoot in the
comments below. So today we'll talk
about how to put the email notification
in a queue with this example and I'll
show you how different the experience is
with and without Q's. Then the second
example would be how to create a Q job
to build the PDF invoice for the order
and the link to code repository for both
examples will be in the description
below. Also we'll talk about how to deal
with Q job failures, how to generally
run the Q and what should be the Q
driver locally on your server and on
production in a remote environment.
Let's begin. First, when you would need
cues in the cases where you don't want
your users to wait, for example, for
sending email notifications, generating
some reports, or processing the uploaded
files. In that case, you show the
success message here on screen and then
put the jobs in the background in the
queue. And here's a simple example. You
create a new task and you need to notify
the users that are assigned to it. And
then those users should get email like
this. But it takes a few seconds to send
that email. So let me show you the time
difference and experience difference if
you do it without Q and with Q in the
code in the controller. We have this. We
create the task in the store method and
then we send the notification to the
assigned users. But in this case I
didn't enable the queue. So what happens
if we open the network tab here and
notify three users. Let's see how much
it takes. Pending. Pending. A few more
seconds and in total 4 seconds for user
to wait. And imagine what happens if
they need to notify 10 users or 20
users. So this is the perfect case for
Laravel cues. And in case of
notification class in Laravel, it can be
queuable very easily. In fact, it is
queuable by default. I just disabled
that. So in the notification task in the
class, it needs to implement shoot Q and
use ceable. That's it. So let's try
again now. And by the way, those emails
were successfully delivered. I'm using
Mail Trap to test emails. So three users
were notified. Now let's try with a Q
create new task. I will use fake filler
chrome extension. Let's notify all four
users in this case. Create task and the
result is immediate. So success on the
screen for the user and then the jobs
for notifications go where it depends on
your setting of the Q driver in the
default. ENV4 Laravel Q connection is
database which means it uses database
driver and the default Laravel comes
with a few tables migrations for jobs
batches and failed jobs. So now if we
look at our database we have table jobs
with four items each of them
representing one notification email to
one user. They are not executed yet.
They are in the queue waiting for their
time and then the developer needs to
start processing the queue and you can
do that with command PHP artisan Q work.
If we launch that running then a few
seconds to send the emails subsequent
emails for some reason go faster and now
in the mail trap we have four new emails
and not only that if we leave Q work in
the background it becomes a background
process. Then look what happens if we
create another task. We create the task
and now if we go to terminal it's
immediately catching the new jobs. So
this is how the cues are supposed to
work on live server and we will talk
about that in a few minutes. There is a
process in the background in the queue
separately from the browser. So the
browser still shows the success result
quickly and then separately you need to
maintain the Q worker to always work and
always be ready for new jobs. And not
only notifications can be queued just
like that. So here's the dogs page for
queueing notification but also in the
same way you can cue mailables also by
adding implements shoot Q and event
listeners in the listener you can add
implements should Q for the same
behavior but what if you have some
general process like for example sending
a PDF invoice for that you would create
a custom job so here's another example
you create the order and you want to get
the invoice PDF and that PDF may take
quite a long time to build a few seconds
again. So we create a separate job with
artisan command php artisan make job for
example generate order invoice and then
in the handle method you do whatever you
want and then put that job into the
queue again the job implements shoot q
andsqable and then in the handle the job
is building the pdf from blade view for
the invoice and to put that job into the
queue we need to dispatch it from
somewhere for example from controller so
in the store method in addition to
request products and order creation we
have this line. So job class dispatch
and you may pass the parameter if you
need. So for example in this case we
have a parameter of order ID which is
automatically processed with PHP8
constructor property promotion. So you
don't need to create a property manually
and then in the handle method you use it
this order id and kind of a pro tip it's
often beneficial to re-query the data
from the database in the Q job because
by the time the job is actually executed
processed the data may have been changed
in the database and as a result if we
fill in the form create order look at
our Q work which is still running it
catches the job executes that and we
have this PDF as a result also you may
want to send that PDF right away. So for
example in the same job you may call the
notification. Now what happens if the
job fails for whatever reason some SQL
query error or typo in the code or
something like that. So the user is
notified about the success but then the
background job isn't executed
successfully. Let's simulate that
scenario and I will show you how it
works for database driver first locally
and then it's a bit different for
production servers with different
driver. We'll talk about drivers in a
few minutes. So for example, in the job
let's make a typo intentionally model
that doesn't exist. Now we execute the
same thing. Create order. Still success.
The order is actually created, but the
background job in the terminal is marked
as done. And this is another important
thing you need to understand about the
cues. If you change something in the
code, Q work doesn't automatically
restart and take the changes of your
code. It works with the Laravel version
at the time when that Q work was
started. So in our case, it actually
succeeded. To simulate the failed job
we need to restart the queue. So let's
stop that one and launch Q work again.
It will listen again for the jobs, but
now with this version of Laravel code.
So let's create another order. And now
what we will see is fail. This is
exactly what I wanted to show you. So
there was a job in the table of jobs.
But now if we refresh it's empty which
means the job is executed. But if it
fails two things happen. First you can
find the actual error in the log
laravel.log. So this is the actual error
like you would find any other error of
Laravel. But also how do you now retry
the job because it's not in the jobs
table anymore. So this is where another
database table comes in. Failed jobs. It
is logged here now with the actual error
exception. And if you want to retry the
job, for example, you fix the error. So
let's get it back. Then we need to
restart Q worker again. Q work again.
And this is what you need to do every
time you deploy new code to production.
You need to restart the Q worker as a
part of your deployment process. And now
our goal is to get that job from failed
jobs to the jobs table. And for that in
the separate tab, we will execute a
command Q retry. There are a few
parameters of job that you can retry.
For example, you can provide the ID of a
job. But in this case, I will just
choose all and it will retry the jobs.
So they are back from failed jobs to
jobs. But actually it is not here
because it's already automatically
executed, done and not failing anymore.
So this is how you generally manually
retry the jobs. But also the jobs
themselves have a few parameters to
specify how many times they should be
retrieded. What are the parameters for
max exceptions, timeout, it's so-called
back off, a lot of parameters that you
can read in the docs of Laravel. Now
let's talk about cues on production
server in live environment. This is
different than local database driver.
Here are other drivers available in
Laravel Q's. And the most popular one
and the most typical one used in Laravel
is Reddis. So to set up the cues on
production, you probably need the
combination of these tools. Reddis
here's the homepage. This tool is not
from Laravel or from PHP. In general
it's much more complicated. And we have
a tutorial Reddus and Laravel 101 with
general overview not for Q specifically
and I will link that in the description
below. But as a part of that tutorial
we have set up for Q connection Reddus.
And then that would be the overview of
Reddus itself. But this is where another
tool comes in which is Laravel Horizon.
This is a dashboard for Q jobs usually
for production server which works
specifically with radius. As an example
we had a tutorial about Q performance
test sending a lot of PDFs and when we
set up the queue with Reddis. Later in
the article, we could monitor how many
jobs were processed and the runtime and
the dashboard of jobs per minute and so
on. Solar Horizon is a must-have and a
very powerful tool to monitor the queue
jobs, but also a few commands like
restarting the queue should happen not
with manually Q termination from
terminal or command Q restart but a
specific command PHP artisan horizon
terminate which would take care of all
of the Q workers in the background and
that background is also provided by a
third tool that you need to know called
supervisor which is again not from
Laravel and not from PHP. P it's a
monitor or process control system to
restart the Q workers automatically if
some of them fail cuz not only job can
fail but also the Q worker process may
crash for whatever reason and in the
Laravel documentation there's a specific
section about supervisor configuration
how to install it and the options that
you may choose and if that sounds
complicated and it is you may install
all of that much easier with help of
tools like for example we're using
Laravel Forge in many of our projects.
It allows to just enable radius
connection for Q with just a few clicks.
Also providing the supervisor
automatically so you don't need to care
about how it works internally. Also, you
can do that with Laravel cloud or not
first-party tools like ploy for
deployment. Disclaimer, I'm not
affiliated with any forge or cloud or
ploy or whatever. I genuinely think that
setting cues up manually on VPS is just
not worth the time. So these are the
basic things about how Q works that I
wanted to explain in this video, but
there's so much more to it. The official
Laravel documentation is pretty long
with a lot of cases. And this is where
the main goal is when working with cues.
Manage them, monitor their performance
restart the jobs, restart the Q workers
scale the Q workers into multiple Q
workers on maybe separate server. So
there's a whole new world how to
optimize cues for really big scale. On
Laravel daily, we have two courses about
Laravel Q's just recently updated cues
in Laravel 12 kind of for beginners. So
it's this video and on top sections like
longunning jobs with timeouts. So, we're
getting deeper into the same topics that
I mentioned in this video. You can see
the chapters on the right, but also
there's a second course called practical
laral cues on live server which is a bit
older almost 2 years ago, but the
fundamentals didn't really change. Same
supervisor, Horizon, and Reddius. So, I
will link both of those courses in the
description below. What do you think
about Q's? Have I missed something
important or what questions do you have
that I could cover in separate videos?
That's it for this time and see you guys
another
