By Theo Brandt ยท Updated
Technical guideSaaS Email Deliverability: SPF, DKIM, DMARC and Streams
Authentication gets you through the door. Separate streams and low complaints keep your login emails arriving.
For a SaaS product, deliverability means three things working together: every sending domain is authenticated with SPF, DKIM and DMARC; mail that must arrive (verification codes, receipts, resets) travels on a different stream from mail people can ignore; and complaints stay low enough that Gmail and Yahoo keep trusting you. If you send more than 5,000 messages a day to Gmail addresses, the first and third are now written rules, not best practice.
Prices checked 7 October 2026; each price links to the vendor page it came from.
What Gmail and Yahoo require
Google's sender guidelines apply to anyone sending more than 5,000 messages a day to Gmail accounts, effective 1 February 2024. Yahoo's sender requirements cover similar ground for bulk senders and say enforcement began the same month and may change over time.
| Requirement | Google (above 5,000 a day) | Yahoo (bulk senders) |
|---|---|---|
| SPF and DKIM | Set up both for your domain | Both for bulk senders; SPF or DKIM at a minimum for everyone |
| DMARC | Publish a policy; enforcement may be set to none | A valid policy of at least p=none, and DMARC must pass |
| Unsubscribe | One-click unsubscribe for marketing and subscribed mail, plus a visible link in the body | A working list-unsubscribe header supporting one-click, plus a visible link; honor requests within 2 days |
| Spam rate | Below 0.10% in Postmaster Tools, never 0.30% or higher | Below 0.3%, measured on mail delivered to the inbox |
Google's page shows the one-click headers as List-Unsubscribe-Post: List-Unsubscribe=One-Click alongside a List-Unsubscribe URL. Most sending providers and lifecycle tools add these for you on marketing mail, so your job is to confirm they are present on a real test message rather than to write them.
Authentication, domain by domain
SPF
SPF is a TXT record on your sending domain listing the servers allowed to send for it. Keep one SPF record per domain and add each provider's include to it rather than publishing a second record. The standard limits an SPF check to 10 DNS lookups, so a domain that includes a helpdesk, a CRM, a marketing tool and a transactional API can fail silently. This is the main reason to put each message class on its own subdomain, with its own short record.
DKIM
DKIM signs each message with a private key held by your provider; receivers verify it against a public key you publish in DNS. Your provider gives you the DNS records and a selector name. Add them, wait for the provider to show "verified", then send a test to a Gmail account and check "Show original" for DKIM: PASS and the domain that signed it.
DMARC
DMARC tells receivers what to do when SPF or DKIM does not line up with the visible From domain, and where to send reports. Publish a TXT record at _dmarc on your domain starting with v=DMARC1; p=none and add a reporting address. Read the reports for a few weeks to find every system that sends as you, fix the ones that fail alignment, and only then move to quarantine and later reject. Moving too early is how a forgotten billing tool ends up blocked.
Separate your streams
A stream is a group of messages with the same reputation risk. Receipts and password resets are wanted by definition; a product announcement is wanted by some. If both share a domain and an IP pool, complaints about the second can slow down the first. Postmark builds this in: its message streams page says "transactional and broadcast traffic never intersect in Postmark, including IP ranges", and a server can hold up to 10 streams. Amazon SES offers dedicated IP pools and lets a configuration set send only through the IPs in its pool.
| Message class | Sending domain | Examples | Unsubscribe link |
|---|---|---|---|
| Account security | Its own subdomain, strict DMARC first | Verification codes, resets, login alerts | No; the message is required |
| Billing | Transactional subdomain | Receipts, invoices, failed-payment notices | No for receipts; reminders follow your policy |
| Lifecycle | Subdomain from your lifecycle tool | Onboarding, trial reminders, feature tips | Yes, with one-click header |
| Announcements | Separate marketing subdomain | Product news, newsletters | Yes, honored within 2 days |
Warm up and watch complaints
A new domain or IP has no history. Start with the recipients most likely to want the mail, such as people who signed up this week, and raise volume only while bounces and complaints stay low. Do not import an old list and send to everyone on day one. With dedicated IPs on SES, the FAQ describes a managed option that tracks warm-up status for you, as opposed to the standard option where you manage the addresses yourself.
Register your domains in Google Postmaster Tools and look at the spam rate for each. Treat a rise toward 0.10% as an incident for the stream responsible: pause the campaign, see which segment was mailed, and remove people who have not engaged. Yahoo's complaint figure is calculated in its own system on mail delivered to the inbox, so do not expect your provider's dashboard to match it.
When mail goes missing: a diagnosis table
| Symptom | Check first | Usual fix |
|---|---|---|
| Verification email not arriving for Gmail users | Raw headers: SPF, DKIM and DMARC results | Fix the failing record; confirm the From domain aligns with the signing domain |
| Newsletter lands in spam but resets are fine | Spam rate in Postmaster Tools for the marketing subdomain | Trim unengaged recipients; check the one-click unsubscribe header |
| DMARC reports show unknown senders | Which service the sending IPs belong to | Authenticate it with its own DKIM, or stop it sending as you |
| Bounce rate spikes after an import | Source of the list and sign-up method | Suppress hard bounces and verify addresses before re-sending |
| SES shows addresses as bounced | Global suppression list entry | Remove only if the address is confirmed valid |
Choosing a sending provider on cost and fit
Lifecycle tools such as Customer.io send on their own infrastructure under your authenticated domain, so check that the tool lets you use a dedicated subdomain and ask about dedicated IPs for your plan. For transactional mail from your own code, five providers are common:
| Provider | At 50,000 emails a month | At 100,000 emails a month | Stream separation |
|---|---|---|---|
| Postmark | Basic $55 | Basic reads $115 at the 125,000 stop on its slider | Built in, separate IP ranges |
| Resend | Pro $20 | Pro $35 | By domain; you design the split |
| Mailgun | Foundation $35 | Scale $90 | By domain; you design the split |
| Amazon SES | $8 at $0.16 per 1,000 | $16 at $0.16 per 1,000 | IP pools and configuration sets |
| SendGrid | Essentials from $19.95 | Pro from $89.95 | Dedicated IPs on higher tiers |
The SES figures are arithmetic on the Essentials per-1,000 rate and exclude any other AWS charges or add-ons. A $55 Postmark bill and a $16 SES bill buy different things: SES leaves suppression handling, templates and reputation monitoring to your own code. Compare feature gaps in Postmark vs SendGrid, Resend vs SendGrid and Mailgun vs SendGrid.
Verdict
Authenticate each sending subdomain, start DMARC at p=none and read the reports before tightening, and put security and billing mail on its own subdomain and stream. If you want that separation without designing it, Postmark is the simplest route; Amazon SES is the cheapest for teams that can build the surrounding pieces; Resend and Mailgun sit between for developer-run sending. Related reading: the transactional versus marketing guide, the email platform security comparison and the list of deliverability-focused platforms.
Frequently asked questions
Do I need DMARC if I send fewer than 5,000 emails a day?
Google's bulk-sender rules apply above 5,000 messages a day to Gmail accounts, but nothing stops a smaller sender from publishing DMARC, and Google lists a policy of none as acceptable. Publishing one with a reporting address costs a few minutes and shows you who else is sending as your domain, which is useful long before you cross the threshold.
Should password resets use a different domain from newsletters?
Yes, use separate subdomains. Postmark says transactional and broadcast traffic never intersect on its infrastructure, including IP ranges, and the same logic applies at the domain level: a complaint-heavy product announcement should not drag down the domain that delivers login codes. Authenticate each subdomain separately.
Is a dedicated IP worth it for a SaaS?
Only when your volume is steady and high enough to build a reputation of your own. Amazon SES lets you group leased IPs into pools and tie a configuration set to a pool, and SendGrid lists dedicated IPs on its higher tiers. At low volume a shared pool run by a provider that polices abuse is usually safer than a cold IP you must warm yourself.
What spam complaint rate should I aim for?
Google's guidance is to keep the rate reported in Postmaster Tools below 0.10% and never reach 0.30%. Yahoo asks senders to stay below 0.3% and measures it on mail delivered to the inbox, so its figure may differ from yours. Treat a rise toward 0.10% as an incident for the stream that caused it.
Which provider has the cheapest sending at 100,000 emails a month?
On published list prices, Amazon SES is lowest at $0.16 per 1,000 emails, which works out to $16 for 100,000 before any extras. Resend Pro lists $35 at 100,000, Mailgun Scale lists $90, and SendGrid Pro starts at $89.95. Price is not the only factor: SES leaves templates, suppression workflows and monitoring to you.