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

shell
# nothing to install — the smtp transport ships with the framework

Complete example

Laravel — STARTTLS on 587, credentials from the environment
# .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.

ProviderHostPortUsernamePasswordNote
QueenSMTP smtp.queensmtp.com587 (STARTTLS) / 465 (SSL) / 2525SMTP username from the dashboardSMTP password$5/year + $0.10 per 1,000; 100 free/day
Gmail smtp.gmail.com587 / 465you@gmail.comApp Password500/day, From must be the account
Amazon SES email-smtp.<region>.amazonaws.com587 / 465 / 2587SES SMTP usernameSES SMTP passwordsandbox 200/day until approved
Office 365 smtp.office365.com587user@yourdomain.commailbox passwordSMTP AUTH must be enabled; 30/min
SendGrid smtp.sendgrid.net587 / 465 / 2525apikeyAPI keyno 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 first

Other languages and frameworks

Examples tested 2026-08-30. If a library changed its API, tell us.

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.