March 12, 2026 (3mo ago)
Written by Temps Team
Last updated March 12, 2026 (3mo ago)
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 | SendGrid | AWS SES | |
|---|---|---|---|
| Cost | ~$6/mo (Temps Cloud) or free self-host | $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 |
Transactional email — password resets, magic links, OTP codes, order receipts — differs from marketing email in three ways that matter for infrastructure:
The six components you actually need:
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.
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.
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"
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.
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:
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.
SES costs $0.10 per 1,000 emails — the cheapest managed option. But the setup process is multi-step:
{
"notificationType": "Bounce",
"bounce": {
"bounceType": "Permanent",
"bouncedRecipients": [
{
"emailAddress": "invalid@example.com",
"status": "5.1.1",
"diagnosticCode": "smtp; 550 User unknown"
}
]
}
}
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.
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 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.
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.
| 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 |
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.
When you run temps setup, you choose your sending method:
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.
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.
Temps email targets the 90% of projects that send under 500 transactional emails per day:
It is not designed for marketing campaigns, newsletters, or bulk sending above 10,000 emails/day.
Temps is self-host free (Apache 2.0) or ~$6/month on Temps Cloud (Hetzner cost + 30% margin, no per-seat fees, no bandwidth bills).
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).
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.
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.
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.
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:
curl -fsSL https://temps.sh/install.sh | bash