Send email with Laravel over SMTP
Configure Laravel Mail for SMTP: .env variables (MAIL_MAILER, MAIL_HOST, MAIL_PORT, MAIL_ENCRYPTION), a Mailable class, queueing, and testing with php artisan tinker. Host table for Gmail, SES and Office 365.
Install
# nothing to install — the smtp transport ships with the framework
Complete example
# .env
MAIL_MAILER=smtp
MAIL_HOST=smtp.queensmtp.com
MAIL_PORT=587
MAIL_ENCRYPTION=tls # use ssl with MAIL_PORT=465 for implicit TLS
MAIL_USERNAME=your-smtp-username
MAIL_PASSWORD=your-smtp-password
MAIL_FROM_ADDRESS=hello@yourdomain.com
MAIL_FROM_NAME="Your App"
# app/Mail/OrderShipped.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public $order) {}
public function envelope(): Envelope
{
return new Envelope(subject: 'Your order has shipped');
}
public function content(): Content
{
return new Content(markdown: 'emails.orders.shipped');
}
}
# anywhere in the app
use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;
Mail::to($order->customer_email)->send(new OrderShipped($order)); // or ->queue() with a queue worker
# quick test
php artisan tinker
>>> Mail::raw('SMTP works', fn($m) => $m->to('you@yourdomain.com')->subject('test'));What to know
- Laravel 9+ uses Symfony Mailer; MAIL_ENCRYPTION=tls means STARTTLS on 587. For port 465 set MAIL_ENCRYPTION=ssl (or MAIL_SCHEME=smtps on Laravel 11+).
- After editing .env run php artisan config:clear (or the cached config keeps the old host).
- Queue mail (->queue()) in production so a slow SMTP handshake never blocks a web request; run php artisan queue:work.
- Use the Mailtrap sandbox host in .env.testing so tests never send real mail.
Same code, different provider
Only the host, port and credentials change. The rules per provider are on the SMTP settings hub.
| Provider | Host | Port | Username | Password | Note |
|---|---|---|---|---|---|
| QueenSMTP | smtp.queensmtp.com | 587 (STARTTLS) / 465 (SSL) / 2525 | SMTP username from the dashboard | SMTP password | $5/year + $0.10 per 1,000; 100 free/day |
| Gmail | smtp.gmail.com | 587 / 465 | you@gmail.com | App Password | 500/day, From must be the account |
| Amazon SES | email-smtp.<region>.amazonaws.com | 587 / 465 / 2587 | SES SMTP username | SES SMTP password | sandbox 200/day until approved |
| Office 365 | smtp.office365.com | 587 | user@yourdomain.com | mailbox password | SMTP AUTH must be enabled; 30/min |
| SendGrid | smtp.sendgrid.net | 587 / 465 / 2525 | apikey | API key | no free plan since 2025 |
Credentials for the example above
Create a free account, verify your sending domain (SPF + DKIM shown in the dashboard), add an SMTP credential, and paste it into the code. 100 emails a day free; $5/year plus $0.10 per 1,000 after that. Prefer HTTPS? The same account has a REST email API.
Get SMTP credentials Test your settings firstOther languages and frameworks
Laravel SMTP — questions
Wrong MAIL_HOST/MAIL_PORT, a firewall blocking the port (cloud providers block 25), or a cached config. Check the host with the SMTP tester and run php artisan config:clear.
tls with port 587 (STARTTLS). Only use ssl when you connect to port 465.
Related Guides
Continue learning with these related articles