I send welcome emails with Mail::to($user)->send(new Welcome($user)) and the request hangs for 3 seconds while SMTP responds. I do not want to install Redis or Horizon. What is the simplest way to push mail onto a queue in Laravel 12?
DEV3 Developer Forum
How do I queue mail in Laravel 12 without Horizon?
Ask a question
Every post is reviewed first. Usually reviewed within 24 hours.
dev3 ·
0
1 reply
dev3 · Accepted answer
You do not need Redis or Horizon. The database queue driver is enough for most small and mid-size apps.
1. Create the jobs table
php artisan make:queue-table # skip if the jobs migration already exists
php artisan make:queue-failed-table
php artisan migrate
New Laravel 12 apps already ship the jobs and failed_jobs migrations and default to QUEUE_CONNECTION=database. Check .env.
2. Queue the mail
Mail::to($user)->queue(new Welcome($user));
queue() replaces send(). Alternatively make the mailable implement ShouldQueue, then even send() is queued.
class Welcome extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
}
3. Run a worker
php artisan queue:work --tries=3 --backoff=30
Locally this is enough. On a server, keep it alive with Supervisor (VPS) or a cron-driven worker on shared hosting:
* * * * * cd /path/to/app && php artisan queue:work --stop-when-empty --max-time=55 >> /dev/null 2>&1
Common pitfalls
- With
QUEUE_CONNECTION=sync(the old default) nothing is actually queued. - Workers are long-running processes and keep old code in memory. Run
php artisan queue:restartafter every deploy. - Pass models, not huge arrays, and let
SerializesModelsreload them. If the row is deleted before the job runs you get aModelNotFoundException. - Use
->afterCommit()orpublic $afterCommit = true;if you queue inside a DB transaction, otherwise the worker may run before the data is committed.
There is also a ready-made example of throttled queued sending in the DEV3 snippet library.
0