[Intermediate] Complete Guide to Asynchronous Processing in Laravel Using Mail & Job Queues
What You’ll Learn
- How to create email templates with Mailable classes
- Configuring mail drivers & queue drivers
- Implementing asynchronous mail sending via Job classes
- Managing queues with Laravel Horizon & Supervisor
- Accessibility best practices for email content
Who This Is For
- Intermediate Laravel engineers implementing email notifications
- Developers looking to speed up response times with async processing
- Project leaders seeking queue visibility and stable operations
Accessibility Level: ★★★☆☆
Covers alt text for images, plain-text fallbacks, color contrast, and language attributes.
1. Introduction: Why Use Mail + Queues?
Synchronous email notifications (user sign-up, password resets, etc.) can slow down your HTTP responses.
By combining Laravel’s job queue with mail, you can offload email sending to the background and return responses immediately.
- Speed: Return HTTP responses instantly
- Reliability: Retry on transient failures
- Scalability: Distribute load across multiple workers
2. Setup: Configuring Mail & Queue Drivers
Add these to your .env
file:
# Mail driver (smtp / mailgun / ses, etc.)
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply@example.com
MAIL_FROM_NAME="YourApp"
# Queue driver (database / redis / sqs, etc.)
QUEUE_CONNECTION=database
Run migration for the database queue:
php artisan queue:table
php artisan migrate
QUEUE_CONNECTION=database
stores jobs in thejobs
table- For Redis: set
REDIS_HOST
etc. in.env
, thenQUEUE_CONNECTION=redis
3. Building a Mailable & Template
3.1 Generate a Mailable
php artisan make:mail WelcomeMail --markdown=emails.welcome
// app/Mail/WelcomeMail.php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class WelcomeMail extends Mailable
{
use Queueable, SerializesModels;
public $user;
public function __construct($user)
{
$this->user = $user;
}
public function build()
{
return $this->subject('Welcome!')
->markdown('emails.welcome');
}
}
3.2 Edit the Markdown View
{{-- resources/views/emails/welcome.blade.php --}}
@component('mail::message')
# Hello, {{ $user->name }}
Thank you for registering! Please click the button below to set up your profile.
@component('mail::button', ['url' => url('/profile')])
Set Up Profile
@endcomponent
Thanks,<br>
{{ config('app.name') }}
@endcomponent
@component('mail::message')
generates a responsive layout- Add
->text('emails.welcome_plain')
for a plain-text version, and includealt
attributes on any images
4. Asynchronous Dispatch with a Job
4.1 Create a Job Class
php artisan make:job SendWelcomeEmail
// app/Jobs/SendWelcomeEmail.php
namespace App\Jobs;
use App\Mail\WelcomeMail;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Mail;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendWelcomeEmail implements ShouldQueue
{
use Queueable, SerializesModels;
protected $user;
public function __construct($user)
{
$this->user = $user;
}
public function handle()
{
Mail::to($this->user->email)
->send(new WelcomeMail($this->user));
}
}
4.2 Dispatch the Job in Your Controller
// app/Http/Controllers/Auth/RegisterController.php
use App\Jobs\SendWelcomeEmail;
protected function registered(Request $request, $user)
{
// Dispatch the job instead of sending synchronously
SendWelcomeEmail::dispatch($user)->delay(now()->addSeconds(10));
}
- Implementing
ShouldQueue
auto-pushes the job to the queue - Use
delay()
to postpone execution
5. Queue Management: Horizon & Supervisor
5.1 Monitor with Laravel Horizon
composer require laravel/horizon
php artisan horizon:install
php artisan migrate
- Provides a dashboard for job status & performance
- Works with Redis queue driver only
5.2 Run Workers with Supervisor
# /etc/supervisor/conf.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=2
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/laravel-worker.log
supervisorctl reread
supervisorctl update
supervisorctl start laravel-worker:*
- Auto-restart and multiple processes ensure high availability
6. Email Accessibility Best Practices
- Alt Text: Always include
alt
attributes on images/buttons - Plain-Text Version: Bundle a fallback plain-text view for screen readers
- Language Attribute: Add
<html lang="ja">
(or appropriate lang) in your email templates - Color Contrast: Ensure button/background text meets WCAG 2.1 AA contrast ratios
7. Summary & Checklist
- Configure mail & queue drivers in
.env
- Design email layouts using Mailable classes & Markdown templates
- Offload mail sending to queues with a
ShouldQueue
Job - Monitor with Horizon and run workers under Supervisor
- Verify alt text, plain-text fallback, language tags, and contrast ratios
You now have a fast, reliable, and accessible email notification foundation. Implement it in your project and delight your users! ♡