Going DeeperPro· 40 min read

Queues & Jobs

Move slow work — sending email, resizing images — into the background so your pages stay fast.

What you will learn

  • Explain why slow work belongs in a queue
  • Create and dispatch a job
  • Run a worker to process the queue

The problem: slow requests

Some tasks take a while — sending a welcome email, generating a PDF, resizing a big image. If you do them during the request, the user stares at a spinner until they finish. A queue fixes this: instead of doing the slow work now, you drop a job onto a waiting list and respond to the user instantly. A separate background process — a worker — picks jobs off the list and runs them afterwards.

  • A job is a class describing one piece of slow work (e.g. "send the welcome email to user 5").
  • A queue is the waiting list those jobs sit on.
  • A worker is a long-running process that takes jobs off the queue and runs them.

Think of a restaurant: the waiter (your web request) takes your order and walks away immediately; the kitchen (the worker) cooks it in the background. The waiter does not stand frozen at your table until the food is ready.

Step 1 — create a job

Artisan generates the job class:

Generate a queued job
php artisan make:job SendWelcomeEmail

This creates app/Jobs/SendWelcomeEmail.php. The class has a handle() method — the code that actually does the slow work — and a constructor where you pass in any data the job needs:

The job carries a user and emails them in handle()
// app/Jobs/SendWelcomeEmail.php
public function __construct(public User $user) {}

public function handle(): void
{
    // the slow work runs here, in the background
    Mail::to($this->user->email)->send(new WelcomeMail($this->user));
}

The constructor public User $user stores the user the job is about (this neat syntax both declares and saves the property). handle() holds the actual work — here, sending the welcome email. Importantly, handle() does not run during the web request; it runs later, on the worker.

Step 2 — dispatch the job

From your controller you dispatch the job — push it onto the queue — and immediately move on:

Queue the work and respond at once
// in the controller, right after creating the user
SendWelcomeEmail::dispatch($user);

return redirect('/dashboard');   // the user sees this instantly

SendWelcomeEmail::dispatch($user) puts the job on the queue and returns straight away — it does not wait for the email to send. So the user is redirected to their dashboard in milliseconds, while the email goes out moments later in the background.

Step 3 — run a worker

Jobs only get processed if a worker is running. You start one in the terminal:

Start a worker to process queued jobs
php artisan queue:work

Note: Output: INFO Processing jobs from the [default] queue. App\Jobs\SendWelcomeEmail ........ RUNNING App\Jobs\SendWelcomeEmail ........ 842ms DONE The worker sits waiting; each time a job is dispatched it picks it up and runs handle(). In production you keep this running with a process monitor like Supervisor (or use Laravel Horizon for a dashboard).

The whole flow, end to end:

  1. A request comes in (e.g. a user just registered).
  2. The controller dispatches a job onto the queue and responds to the user immediately.
  3. The job waits in the queue (a database table or Redis).
  4. A running worker (php artisan queue:work) picks the job up.
  5. The worker runs the job’s handle() method — the slow email actually sends.

Tip: Set QUEUE_CONNECTION=database in .env and run php artisan queue:table && php artisan migrate to use a simple database-backed queue while learning. If a job throws an error, Laravel can retry it, and permanently failed jobs land in a failed_jobs table you can inspect.

Q. Why dispatch slow work to a queue instead of doing it during the request?

Answer: Dispatching a job returns immediately, so the page responds fast; a separate worker runs the job’s handle() afterwards — ideal for emails, image processing and reports.

✍️ Practice

  1. Create a job, dispatch it from a controller, and process it with php artisan queue:work.
  2. Add an artificial sleep(3) in handle() and confirm the page still responds instantly.

🏠 Homework

  1. Queue a “send welcome email” job that runs when a user registers, and watch it process in a worker.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →