Laravel Queues and Jobs for Heavy Tasks

Have your users ever waited seconds after clicking "Submit", just because your app was sending emails or processing images behind the scenes? Heavy tasks like these should never ma...

Laravel Queues and Jobs for Heavy Tasks

Have your users ever waited seconds after clicking "Submit", just because your app was sending emails or processing images behind the scenes? Heavy tasks like these should never make users wait. This is where Queues and Jobs come in: they move heavy work into the background so responses stay fast. This tutorial covers Queues in Laravel 10/11 from scratch with real code.

Why You Need Queues

By default, every request is processed synchronously — the user waits until all code finishes. If an action triggers sending 100 emails or compressing a 5 MB image, the request can take several seconds. With a queue, you simply hand off the work to the queue, return an instant response, and let a worker process it in the background.

  • Faster responses: users don't wait for heavy tasks.
  • Load resilience: spikes of work are processed gradually, not all at once.
  • Automatic retries: failed jobs can be retried without disrupting the user.

1. Configure the Queue Driver

Laravel supports several drivers: sync (default, runs immediately), database, redis, and more. To start, the database driver is easiest since it needs no extra service. Set it in .env:

QUEUE_CONNECTION=database

Then create the jobs table and run the migration:

php artisan make:queue-table
php artisan migrate

For high traffic, redis is much faster. Just switch to QUEUE_CONNECTION=redis once a Redis server is available — your job code doesn't change at all.

2. Create Your First Job

Create a job class with artisan:

php artisan make:job SendWelcomeEmail

The file appears at app/Jobs/SendWelcomeEmail.php. Pass the data you need through the constructor, and put the heavy logic in the handle() method:

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public User $user) {}

    public function handle(): void
    {
        Mail::to($this->user->email)
            ->send(new WelcomeMail($this->user));
    }
}

The key here is the ShouldQueue interface — it tells Laravel this job should be queued rather than run immediately.

3. Dispatch the Job

From a controller, just call dispatch():

public function store(Request $request)
{
    $user = User::create($request->validated());

    SendWelcomeEmail::dispatch($user);

    return redirect()->route('dashboard')
        ->with('success', 'Account created, email on its way.');
}

Notice the response returns instantly. The job goes into the queue, and email sending happens in the background. You can also delay a job with delay():

SendWelcomeEmail::dispatch($user)->delay(now()->addMinutes(5));

4. Run the Worker

A dispatched job only sits in the queue; something must execute it. Run a worker:

php artisan queue:work

The worker keeps running, picks up jobs one at a time, and runs the handle() method. For development, use queue:listen which reloads code automatically. For production, use queue:work because it is more efficient.

Important: after changing job code, restart the worker so changes are picked up:

php artisan queue:restart

5. Retries and Failed Jobs

Jobs can fail — an SMTP connection drops, a third-party API errors out. Laravel can retry automatically. Set the attempt limit via properties on the job:

public $tries = 3;
public $backoff = 10; // wait 10 seconds between attempts

Once all attempts are exhausted, the job lands in the failed_jobs table. Set up the table:

php artisan make:queue-failed-table
php artisan migrate

List, retry, or clear failed jobs:

php artisan queue:failed
php artisan queue:retry all
php artisan queue:flush

You can also handle failure specifically with a failed() method on the job, for example to notify an admin.

6. Real Example: Processing Images

Compression and thumbnail generation are heavy tasks. Wrap them in a job:

class ProcessProductImage implements ShouldQueue
{
    use Dispatchable, Queueable, SerializesModels;

    public function __construct(public Product $product) {}

    public function handle(): void
    {
        $img = Image::read($this->product->image_path)
            ->scale(width: 800);
        $img->save(storage_path('app/public/thumbnails/'
            . $this->product->id . '.jpg'));
    }
}

Dispatch it after the upload finishes, and the user never waits for image processing to complete.

7. Keeping Workers Alive with Supervisor

On a production server, the queue:work process can die at any time. Supervisor is a process monitor on Linux that automatically restarts the worker. Example config at /etc/supervisor/conf.d/laravel-worker.conf:

[program:laravel-worker]
command=php /var/www/app/artisan queue:work --tries=3 --timeout=90
autostart=true
autorestart=true
numprocs=2
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/app/storage/logs/worker.log

Load the config:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

Now the worker always runs even if the server restarts. Your app handles heavy tasks without making users wait — the same pattern works for reports, WhatsApp notifications, Excel exports, and other batch processes.

Yudhi
Written by
Yudhi
Founder & Lead Developer, GudangCode

Yudhi is the founder of GudangCode and a Laravel developer who has built dozens of ready-to-use business information systems — from POS and HRIS to management apps. He writes guides and articles on GudangCode to help Indonesian developers run, understand, and deploy Laravel source code correctly.

LaravelPHPMySQLSistem Informasi Bisnis See all articles by Yudhi
Want the full source code & apps?

Sign up free to download ready-to-use business applications, information systems, and Laravel source code.

Sign Up Free & Download
Queue Job Laravel Programming & Laravel
Share this article
Back to Blog
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →

Get Full Access Now!

Join our membership and unlock exclusive access to all premium features. Fast, easy, and ready to use instantly.

Join Membership Now
Tim Support
Online
Isi data dulu untuk mulai chat:
Beri rating & testimoni sebelum menutup:
Live chat by gudangcode.com