How to Set Up SMTP Relay in Laravel
Learn how to set up SMTP relay in Laravel with step-by-step .env configuration, testing tips, and a transactional API alternative.
What Is an SMTP Relay and Why Use One with Laravel
An SMTP relay is a third-party service that accepts outgoing mail from your application and forwards it to recipient inboxes on your behalf. Laravel's built-in mail()-based sending, or a local Postfix install on your server, can technically send email too. But it usually gets flagged as spam. Fast. This article walks through how to set up SMTP relay in Laravel so your transactional messages actually reach the inbox instead of the junk folder.
The problem is reputation. A shared hosting IP that dozens of other apps also send from has no history with Gmail, Outlook, or Yahoo. Spam filters look at sender reputation, authentication records, and sending volume before deciding whether a message lands in the inbox or the junk folder. A relay provider like Mailgun, SendGrid, or Postmark has already built that reputation, and it manages retries, bounce processing, and IP warmup so you don't have to write that logic yourself.
Relays are preferred over local mail servers whenever an app sends anything transactional: password resets, invoices, order confirmations, signup verification links. Marketing sends benefit too, but transactional email is the one category where a missed delivery directly breaks a user flow — nobody resets their password twice. If you want the fuller picture on inbox placement, this guide on email deliverability best practices covers reputation scoring in more depth.
Prerequisites Before You Begin
Before touching any config file, gather a short list of things. Skipping this step is the most common reason setup drags on for an afternoon instead of ten minutes.
- A working Laravel installation (Laravel 8 through 11 all use the same mail config structure).
- Access to the project's
.envfile, either locally or on the deployed server. - An account with an SMTP relay provider — Mailgun, SendGrid, Postmark, Amazon SES, or a similar service.
- Relay credentials: SMTP host, port, username, and password (or an API key used as the password).
- A verified sending domain on the provider's side, so outgoing mail isn't rejected before it even leaves.
Most providers show these credentials right on their dashboard under a section labeled "SMTP" or "Integration." Copy them somewhere safe. You'll need every field.
Laravel SMTP Configuration — Step-by-Step Setup
Laravel keeps mail configuration split between two files: config/mail.php, which defines the structure of each mailer, and .env, which holds the actual values. You almost never need to edit config/mail.php directly — the defaults already read from environment variables. If you've never done this before, learning how to set up SMTP relay in Laravel really just comes down to filling in the right environment variables in the right order.
- Open your
.envfile and setMAIL_MAILER=smtp. This tells Laravel to use the SMTP transport instead oflog,sendmail, or an API driver. - Set
MAIL_HOSTto the relay's SMTP server address, for examplesmtp.mailgun.orgorsmtp.sendgrid.net. - Set
MAIL_PORT. Common values are 587 for TLS, 465 for SSL, or 2525 as a fallback when 587 is blocked. - Set
MAIL_USERNAMEandMAIL_PASSWORDto the credentials your provider issued. For some providers, the "username" is literally the wordapikey, and the password is your actual API key. - Set
MAIL_ENCRYPTIONtotlsin most cases. Leave it blank only if the provider explicitly says port 25 without encryption. - Set
MAIL_FROM_ADDRESSandMAIL_FROM_NAME. These control the default "From" header, and they should match a domain you've verified with the relay. - Run
php artisan config:clearafter saving. Laravel caches config aggressively, and stale values are the top reason a fresh setup "doesn't work" on the first try.
Here's what a typical block looks like once filled in:
| Variable | Example value | Purpose |
|---|---|---|
| MAIL_MAILER | smtp | Selects the transport driver |
| MAIL_HOST | smtp.mailgun.org | Relay server address |
| MAIL_PORT | 587 | Connection port |
| MAIL_ENCRYPTION | tls | Encrypts the SMTP session |
| MAIL_USERNAME | postmaster@yourdomain.com | Relay account identifier |
| MAIL_PASSWORD | your-api-key | Relay authentication secret |
Nothing exotic here. It's mostly copy-paste, and the mistakes usually come from mismatched port and encryption combinations, not typos.
Testing Your SMTP Relay Connection in Laravel
Never trust a config change until an actual email lands. Test it.
- Open a Tinker session with
php artisan tinker. - Run
Mail::raw('Test message from Laravel SMTP relay', function ($message) { $message->to('you@example.com')->subject('SMTP test'); });. - Check your inbox — and your spam folder, just in case — within a minute or two.
- If nothing arrives, check
storage/logs/laravel.logfor the actual SMTP error returned by the provider. - Cross-check the result against your provider's dashboard, which usually logs every attempted send with a delivery status.
Two errors show up constantly. A connection timeout usually means the port is blocked by your hosting provider or firewall, which is depressingly common on cheap VPS plans that block outbound port 25 by default. An authentication failure almost always means the username and password were swapped, or an API key was pasted with a trailing space. If you want a more systematic way to verify deliverability beyond a single test send, there are dedicated email deliverability test tools that check spam scoring, authentication, and content flags in one pass.
Laravel Transactional Email API — An Alternative to SMTP
SMTP isn't the only option. Every major relay provider also exposes a REST API, and Laravel has official or community driver packages for most of them — Mailgun, SendGrid, Postmark, and SES all work this way.
The API route skips the SMTP handshake entirely. Instead of opening a socket connection, authenticating, and streaming the message line by line, your app makes a single HTTPS POST request with the email payload attached as JSON. This matters because a good number of hosting environments block or throttle SMTP ports, while port 443 is almost never blocked. API sending is also generally faster for high-volume transactional apps, since there's no persistent connection to negotiate per message.
Setup differs slightly per provider, but the pattern is consistent:
- Install the provider's Laravel package via Composer, for example
composer require symfony/mailgun-mailer symfony/http-clientfor Mailgun. - Set
MAIL_MAILER=mailgun(or the equivalent driver name) in.env. - Add the API key and domain as environment variables, following the specific keys the driver expects.
- Clear config cache and send a test message the same way you would with SMTP.
SMTP still has its place — it's universal, and it works the same regardless of provider, which is handy if you ever switch relays. Teams building outside Laravel run into the identical port-blocking issue; the reasoning in this SMTP relay guide for Node.js apps applies just as well conceptually, even though the code differs.
Securing Your SMTP Credentials
Treat SMTP passwords and API keys like production database credentials. Because that's essentially what they are.
- Never commit
.envto version control. Confirm it's listed in.gitignore— it is by default in Laravel, but double-check after any framework upgrade. - Use separate credentials for staging and production. A leaked staging key shouldn't be able to send mail from your production domain.
- Rotate API keys periodically, especially after a team member leaves or a laptop gets lost. Most providers let you generate a new key
and disable the old one without downtime.
If your provider supports IP allowlisting, restrict access to the servers that actually send mail. Pair that with least-privilege access in your cloud and deployment tools so only the application environment can read the mail secrets.
Troubleshooting Common SMTP Relay Problems
Even with everything configured correctly, mail delivery can still fail for reasons outside Laravel. When that happens, work through the problem systematically:
- Verify the hostname, port, encryption setting, username, and password in your environment file.
- Check whether your provider requires a verified sender domain or a specific From address.
- Make sure outbound SMTP traffic is allowed by your server firewall or hosting provider.
- Inspect the provider’s activity logs for rejection messages, rate limits, or authentication failures.
- Send a test message from Laravel Tinker or a simple route to isolate the issue from the rest of your app.
If messages are accepted but never arrive, the problem may be deliverability rather than delivery. In that case, review your SPF, DKIM, and DMARC setup, and confirm that your DNS records match the SMTP service you are using.
Final Thoughts
Setting up SMTP relay in Laravel is mostly about using the right credentials, choosing a reliable provider, and keeping your configuration clean and secure. Once it is working, you gain much better deliverability, visibility, and control than with a basic mail server.
With a solid relay in place, your application can send mail consistently in development, staging, and production without unnecessary headaches.
On this page
← All articlesOne click. It tells us what to write next.
No ratings yet — yours would be the first.
Comments
Comments are read before they appear.