Self-Host Transactional Email Instead of SendGrid
SMTP setup, SPF, DKIM and DMARC authentication, and delivery pipelines with self-hosted Postal. The same deliverability, no monthly bill, no vendor lock-in.
You don't need SendGrid to send password resets and magic links. AWS SES costs $0.10 per 1,000 emails. Self-hosted tools like Postal handle it for free. And deployment platforms like Temps bundle SMTP, SES, and Scaleway email directly — no third-party relay, no separate API key, no additional infrastructure.
TL;DR: Most apps only need transactional email for auth flows — password resets, magic links, verification. SendGrid starts at $15+/month for features most projects never use. AWS SES costs $0.10/1,000 emails but requires sandbox escape, SNS bounce handling, and IAM setup. Temps includes SMTP, SES, and Scaleway providers built in — configure once during
temps setupand your apps send email with no external relay.
Temps vs SendGrid vs AWS SES
| Temps | SendGrid | AWS SES | |
|---|---|---|---|
| Cost | Free self-host (Apache 2.0); Temps Cloud is a coming-soon managed add-on, not yet priced | $15+/mo (Essentials) | $0.10/1,000 emails + AWS overhead |
| Built-in SMTP | Yes (no relay needed) | No (hosted relay) | No (relay via AWS endpoints) |
| SES integration | Yes (native provider) | No | Yes (it is SES) |
| Scaleway provider | Yes (native) | No | No |
| Bounce handling | Automatic | Automatic | Manual (SNS + Lambda) |
| DKIM setup | Automatic via temps setup | Manual DNS records | 3 CNAME records |
| Per-seat fees | None | None | None |
| Dashboard setup | Included in deployment platform | Separate service | AWS Console |
| Extra infrastructure | None (same binary) | API key + separate service | SNS + IAM + CloudWatch |
| License | Apache 2.0 | Proprietary SaaS | AWS proprietary |
What Does Transactional Email Actually Require?
Transactional email — password resets, magic links, OTP codes, order receipts — differs from marketing email in three ways that matter for infrastructure:
- Triggered by user action, not scheduled campaigns. Latency matters. A password reset that takes 2 minutes to arrive feels broken.
- Legally exempt from unsubscribe requirements. CAN-SPAM and GDPR treat transactional email as necessary for contract performance — no consent banner, no unsubscribe link required.
- Low volume, high importance. A typical SaaS with 500 daily active users sends 200-500 transactional emails per day. Deliverability matters more than bulk throughput.
The six components you actually need:
- SMTP server — accepts outbound mail from your app
- SPF, DKIM, DMARC — DNS records that determine inbox placement
- Bounce handling — suppress future sends to invalid addresses
- Rate limiting — warm new IPs gradually (50-200 emails/hour at start)
- Retry queue — exponential backoff on temporary delivery failures
- Template engine — inject dynamic content into HTML emails
How Do SPF, DKIM, and DMARC Work?
These three DNS records are non-negotiable. Google's sender requirements mandate SPF and DKIM for all senders. Skip any one and your email rates spike in spam folders.
SPF (Sender Policy Framework)
Lists the IP addresses authorized to send email for your domain:
yourdomain.com TXT "v=spf1 ip4:YOUR_SERVER_IP ~all"
Pitfall: SPF has a 10-lookup limit. Each include: directive counts. Add too many third-party senders and the entire record breaks.
DKIM (DomainKeys Identified Mail)
Adds a cryptographic signature to every outgoing message. The receiving server looks up your public key in DNS and verifies the message wasn't tampered with:
default._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY"
DMARC (Domain-based Message Authentication)
Ties SPF and DKIM together and tells receiving servers what to do when authentication fails:
_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com"
Start with p=none for the first two weeks to monitor without blocking. Move to p=quarantine once you've confirmed all legitimate senders pass SPF and DKIM.
Can You Build Your Own Transactional Email System?
Yes. The sending part is straightforward with Nodemailer and a simple retry queue:
import nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({
host: 'localhost',
port: 587,
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
interface EmailJob {
to: string;
subject: string;
html: string;
retries: number;
lastAttempt?: Date;
}
async function sendWithRetry(job: EmailJob, maxRetries = 3) {
try {
await transporter.sendMail({
from: '"Your App" <noreply@yourdomain.com>',
to: job.to,
subject: job.subject,
html: job.html,
});
} catch (error) {
if (job.retries < maxRetries) {
job.retries++;
job.lastAttempt = new Date();
const delay = Math.pow(2, job.retries) * 1000;
setTimeout(() => sendWithRetry(job, maxRetries), delay);
} else {
console.error(`Failed after ${maxRetries} retries: ${job.to}`);
}
}
}
This handles the happy path. What it's missing:
- DKIM signing (another 100 lines + OpenDKIM configuration)
- Bounce classification (hard vs. soft) and suppression lists
- IP warmup management
- Blocklist monitoring (MXToolbox, Spamhaus)
- Log rotation for mail logs
Running Postfix on a VPS works well under 1,000 emails/day. Beyond that, IP reputation becomes the bottleneck. ISPs throttle new IPs heavily — warmup takes 2-4 weeks of gradually increasing volume.
Is AWS SES Worth the Complexity?
SES costs $0.10 per 1,000 emails — the cheapest managed option. But the setup process is multi-step:
- Request production access — SES starts in sandbox mode. Submit a use-case request; AWS reviews manually (1-3 business days).
- Verify your domain — Add a CNAME to DNS. SES enables domain-level sending.
- Configure DKIM — SES provides three CNAME records. Add all three.
- Set up bounce handling — Create an SNS topic for bounces and complaints, subscribe a Lambda function or SQS queue to process them. Ignore bounces and AWS suspends your account.
{
"notificationType": "Bounce",
"bounce": {
"bounceType": "Permanent",
"bouncedRecipients": [
{
"emailAddress": "invalid@example.com",
"status": "5.1.1",
"diagnosticCode": "smtp; 550 User unknown"
}
]
}
}
- Create IAM credentials — Generate SMTP credentials from the SES console.
- Set up a configuration set — Track delivery metrics via CloudWatch.
The cost math for a typical SaaS:
| Email type | Daily volume | Monthly cost |
|---|---|---|
| Password resets | ~20 | $0.06 |
| Verification emails | ~50 | $0.15 |
| Magic links | ~100 | $0.30 |
| Activity notifications | ~200 | $0.60 |
| Total | ~370 | ~$1.11 |
SES is the right call if you're already running Lambda functions and CloudWatch dashboards — the incremental cost is negligible. If you're not in the AWS ecosystem, the onboarding overhead (SNS, IAM, CloudWatch) exceeds what most small projects justify.
What Are the Best Open-Source Transactional Email Alternatives?
Postal
Postal is a full-featured, open-source mail delivery platform written in Ruby — the closest self-hosted equivalent to SendGrid.
What you get: SMTP server with web UI, DKIM signing, webhook notifications for delivery events, click and open tracking, IP pool management, HTTP API and SMTP interface.
Resource cost: Minimum 2GB RAM (4GB recommended), MySQL/MariaDB, RabbitMQ for job processing.
git clone https://github.com/postalserver/postal
cd postal
docker compose up -d
Best choice if you need a self-hosted SendGrid replacement with full tracking and multiple sending domains.
Listmonk
Listmonk is primarily a newsletter manager but handles transactional email through its API. Written in Go — fast and resource-efficient (~100MB RAM, PostgreSQL, single binary).
Good choice if you need both transactional and marketing email in one tool. For transactional-only, it's more than you need.
Mailu
Full mail server suite — SMTP, IMAP, webmail, antispam — packaged in Docker containers. Overkill for transactional-only, but the right choice if you also want to receive email on your domain.
Open-source options compared
| Feature | Postal | Listmonk | Mailu |
|---|---|---|---|
| Transactional API | Yes | Yes | SMTP only |
| DKIM signing | Built-in | Manual | Built-in |
| Bounce handling | Automatic | Manual | Automatic |
| Web UI | Yes | Yes | Yes |
| Min. RAM | 2GB | 100MB | 2GB |
| Receive email | No | No | Yes |
| Cost | Free | Free | Free |
| Setup complexity | Medium | Low | High |
How Does Temps Handle Transactional Email?
Temps includes SMTP, SES, and Scaleway email providers built in — no third-party relay required. The email system is part of the same single Rust binary that handles deployments, analytics, error tracking, and uptime monitoring. There is no separate service to configure or pay for.
Three email providers, zero extra services
When you run temps setup, you choose your sending method:
- SMTP — point at any SMTP server (including a local Postfix instance)
- SES — native AWS SES integration, no relay needed
- Scaleway — Scaleway Transactional Email, built-in provider
Your deployed applications send email through the built-in endpoint with no additional configuration. Auth flows — password resets, magic links, OTP codes, email verification — work immediately.
What Temps configures automatically
- DKIM key generation
- SPF, DKIM, and DMARC DNS records (displayed during setup)
- Retry queue with exponential backoff
- Bounce processing
No extra moving parts
A standard self-hosted email stack requires: SMTP server + queue processor + bounce handler + monitoring dashboard. With Postal, add MySQL and RabbitMQ. With SES, add Lambda and SNS.
Temps collapses this into the same binary already running your deployments. No extra containers, no extra services, no extra monthly bills.
What Temps email is designed for
Temps email targets the 90% of projects that send under 500 transactional emails per day:
- Auth flows: magic links, OTP codes, password resets, email verification
- System notifications: deploy success/failure alerts, uptime alerts
- Low-volume transactional: order confirmations, account activity notifications
It is not designed for marketing campaigns, newsletters, or bulk sending above 10,000 emails/day.
Temps is free to self-host (Apache 2.0), with no per-seat fees and no bandwidth bills. Temps Cloud, a managed layer adding telemetry retention, offsite backups, and AI credits, is coming soon and not yet priced.
FAQ
Will self-hosted email land in spam?
Not if you configure DNS correctly. SPF, DKIM, and DMARC are the three records that determine inbox placement. Google's sender guidelines require all three for reliable delivery. Start with a 2-4 week warmup — send to small batches first and increase volume gradually. Monitor sender reputation through Google Postmaster Tools (free).
How many emails can you send from a VPS before getting blocked?
Most cloud providers allow outbound SMTP on ports 587 and 465 but block port 25 by default. Hetzner requires a manual unblock request. A single VPS with a warmed IP reliably handles 1,000-2,000 emails per day. Beyond that, you need dedicated IPs and professional-grade reputation management. Rate-limit yourself to 100-200 emails per hour when starting.
Is AWS SES better than running your own SMTP?
For deliverability, yes — AWS has established IP reputation across massive pools. For simplicity, no — SES requires sandbox escape, SNS bounce handling, IAM credentials, and CloudWatch monitoring. If you're already deep in the AWS ecosystem, SES costs $0.10/1,000 emails and is a reasonable choice. If you're not, the setup overhead typically exceeds what small projects justify.
Can you use a free SMTP relay?
Brevo (formerly Sendinblue) offers 300 free emails per day. These work for prototyping. The tradeoff: shared IP reputation, strict rate limits, and limited customization. For production apps, shared infrastructure creates deliverability risk. Dedicated sending — your own SMTP or a platform with native providers — gives you control over your sender reputation.
What's the cheapest way to send transactional email?
- Self-hosted Postfix on an existing VPS: effectively $0 additional cost
- AWS SES: $0.10/1,000 emails — roughly $1/month for a typical SaaS auth flow
- Temps (self-hosted): free — email is part of the platform
- Temps Cloud: a coming-soon managed add-on for telemetry retention, offsite backups, and AI credits, on top of the free self-hosted platform — not yet priced
- SendGrid Essentials: $15+/month
Stop Overpaying for Password Reset Emails
Transactional email is a solved problem sold as a monthly subscription. You don't need $15/month to send 200 password resets a day. You need an SMTP server, three DNS records, and a retry queue.
The right option depends on your stack:
- Already on AWS: SES at $0.10/1,000 emails is a natural fit
- Want full control, some ops overhead: Postal or Mailu self-hosted
- Want to eliminate the category entirely: Temps bundles SMTP, SES, and Scaleway providers with your deployment platform
curl -fsSL https://temps.sh/install.sh | bash
Get weekly updates