Email deliverability for small teams: SPF, DKIM and DMARC without breaking mail
Deliverability sounds like a marketing problem, which is why small teams never check it until it's an operations problem. Then the pattern is always the same: a customer says "I never got the invoice," a password reset goes to spam, a two-factor code doesn't arrive, and someone spends a day blaming the mail provider when the real issue is a DNS record nobody has read since the company was three people. This is the 45-minute audit that keeps your mail landing — and the runbook for the morning it stops.
1. Why this is an ops problem, not a marketing problem
- Money and access both ride on email. Invoices, payment receipts, password resets, MFA codes, incident notifications. If your domain's mail silently starts landing in spam, you don't see a dashboard turn red — you see customers pay late, lock themselves out, and assume you've gone quiet during an outage.
- Silent failure is the default. Nothing bounces. The receiving server quietly scores your mail down, and the only symptoms arrive through humans: "didn't get it," "check your spam folder." That makes deliverability a monitoring problem like any other silent failure — you put a check on it, you don't wait for someone to notice.
- Every new tool is a new sender. The CRM, the helpdesk, the e-sign tool, the newsletter platform, the CI server — each one wants to send email as your domain. Each addition is a change to your DNS, whether or not anyone treated it like one. Deliverability usually breaks the week a new tool goes live, not the week DNS expires.
2. The 45-minute audit, step by step
- Inventory every service that sends as your domain. One list: mail provider (Google Workspace, Microsoft 365, Fastmail), billing (Stripe, QuickBooks), helpdesk, newsletter, CRM, e-sign, CI. Ask "who emailed a customer last week?" — every answer is a sender. If a tool isn't on the list, its mail is either failing or about to.
- Look up all three records in parallel. From any terminal:
dig +short TXT yourdomain.com(SPF lives here),dig +short TXT _dmarc.yourdomain.com, anddig +short TXT s1._domainkey.yourdomain.com(DKIM selectors vary:google,selector1/selector2,k1,fm1). Five minutes, no admin panel required — DNS is the ground truth, not the vendor's dashboard. - Count your SPF lookups. SPF has a hard limit of 10 DNS lookups per evaluation, counting every
include:,a,mx, andexistsmechanism — including the nested ones inside your vendors' own includes. Over 10, some receivers treat the whole record as broken. If you're at 7+, pruning is a this-quarter task, not a someday task. - Verify DKIM validates for every sender, not just mail. Send yourself a message from each system (billing test invoice, helpdesk ticket reply, newsletter proof) and view the original headers:
Authentication-Resultsshould readspf=pass dkim=pass dmarc=pass. A tool sending unsigned mail has been coasting on SPF alone — that's a finding. - Check where DMARC reports go — if anywhere. A DMARC record with no
rua=address means you published a policy but blinded yourself: you'll never see who's spoofing you or which legitimate tool is misfiring. A free aggregate-report parser turns the XML into "these four services send as you; one fails alignment."
3. SPF: one record, ten lookups, and the -all question
- Exactly one SPF record per domain. Two
v=spf1records is the most common self-inflicted wound — usually someone "adding a tool" by creating a second record instead of merging into the existing one. Receivers treat duplicate SPF records as a permanent fail. Merge everything into oneTXTrecord; delete the strays the same day. - Every sender gets an
include:in that one record. A sane small-team record looks likev=spf1 include:_spf.google.com include:sendgrid.net ~all. Removing a churned tool's include is the sending-domain version of the offboarding checklist: when the login is revoked, the right to send as you is revoked too. - The 10-lookup budget is shared with your vendors. Your mail provider's include may itself cost 2–3 lookups; the newsletter tool's can cost 5. Two or three "innocent" vendor includes and you're near the ceiling before the helpdesk asks to be added. At 8 lookups, stop adding and start consolidating senders — or move to a provider with SPF flattening and verify after every vendor change.
~allnow;-allonly after DMARC proves the sender list.-all(hardfail) punishes every tool you forgot to add, and the punishment lands on customers waiting for invoices. The honest sequence:~allwhile you're still discovering senders, then tighten once a month of DMARC reports proves the list is complete.
4. DKIM: 2048-bit keys and two live selectors
- Enable DKIM everywhere, not just on the mail provider. Google and Microsoft sign by default; billing, helpdesk, and marketing tools often don't. Every unsigned message from your domain is scored on SPF alone — one legacy vendor with a broken signing setup is enough to drag the whole domain's reputation down.
- Generate 2048-bit keys. 1024-bit DKIM keys are practical to attack and several receivers score them down. Any admin panel that offers a key-size dropdown: take the largest. It costs nothing at setup and saves one migration later.
- Run two selectors at all times. The part nobody does and everyone eventually needs: publish selector 1 and selector 2, sign with one, and when you rotate, sign with the second for a week of clean headers before deleting the first. Rotation without downtime is the entire point — the same new-live-before-old-dead logic as secrets rotation.
- Put rotation on the calendar anyway. DKIM keys never expire, which is exactly why they never rotate — until an admin screenshot leaks a private key into a ticket, or a departed contractor still has access to the signing system. Quarterly selector rotation rides along with the secrets pass: ten minutes with two selectors, a crisis without them.
5. DMARC: the road from p=none to p=reject
- Day 0 — publish
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com.p=nonechanges nothing about delivery; it only switches on the reporting firehose. It costs nothing and blocks nothing — publish it today even if you do nothing else from this checklist. - Weeks 1–4 — read the aggregate reports. Raw XML is unreadable; free parsers aren't. You're looking for three things: legitimate senders you forgot (add them to SPF/DKIM), services failing alignment (fix or kill them), and volume you don't recognize (someone is spoofing you — the reason DMARC matters even if you never send marketing mail).
- Week 5 —
p=quarantine; pct=25, only after a clean month.pct=25sends a quarter of failing mail to spam: a controlled burn instead of a bonfire. Bump 50 → 100 over two weeks while watching your own inbox and one friendly customer's. - Then
p=reject, and setsp=for subdomains. Reject makes spoofed mail from your domain die on arrival. While you're there: subdomains inherit the policy unlesssp=says otherwise, and attackers love subdomains precisely because nobody configured them. - The one place tighter is worse: mailing lists and forwarders. Old-school forwarding and lists break DKIM signatures, and strict DMARC then bounces mail your customers asked for. If your audience lives on lists, hold at
quarantineor relax alignment (adkim=s/aspf=s). "Tighter" is not automatically "better."
6. Monday-morning runbook: mail stopped arriving
- Scope the blast radius first. Test mail from your domain to Gmail, Outlook, and one small provider — and check the spam folders, not just the inbox. All receivers failing = your domain or provider. One receiver failing = reputation with that receiver. Same rule as the opening minutes of any incident: measure before you change.
- Diff DNS against last-known-good. What changed in 7 days? New marketing tool, new billing provider, a second SPF record someone added to "fix" things, a lapsed domain renewal (
whois— expired domains stop sending permanently). Keep a copy of your records in your ops docs so the diff is onedigapart; the record-saving habit belongs in your DNS runbook. - Check blacklists — then hunt the reason you're on them. Spamhaus, Barracuda, Microsoft SNDS. The listing is a symptom; the disease is usually a compromised mailbox, an open relay, or a script sending through your domain. Delist without fixing the source and you're back by Thursday — and if the source is a stolen credential, that's an exposed-key incident, not a deliverability problem.
- Check the provider's status page before touching anything. Gmail, Outlook, and bulk-mail vendors all publish sender-facing incidents. If the vendor is degraded, your job is to delay the send and tell the team — every DNS edit made during someone else's outage is a second incident queued behind the first.
- Tell the humans early, with the template. "Invoice delivery is degraded for some recipients; today's invoices are being re-sent manually; next update 2pm" beats silence. Use the status update template: customers forgive delivery problems, not discovering them from their own bank statement.
7. Keep it from drifting back
- One 20-minute quarterly review. Re-run the parallel lookups, diff against the saved records, parse the last month of DMARC reports. The review stays short because the reports did the watching all quarter — which is the same reason the restore test stays short: the check is scheduled, so the panic isn't.
- The new-sender gate. No tool sends as your domain until SPF/DKIM are updated — one line in the weekly ops check: "new tool sending email this week?" Trials convert into senders the same way they convert into invoices, silently; the gate is what makes the conversion visible.
- Alert on the 2am failure modes. DMARC reports dropping to zero (DNS broke or the report address died), your own monitoring notifications failing (the thing watching the mail can't use the mail), and a monthly seed-inbox test for spam placement. Cron handles all three; keeping it quiet is the craft in the cron monitoring checklist.
- Senders are vendors: review them annually. Every service allowed to send as your domain can also impersonate it. They belong in the annual vendor security review — what data they hold, who can log in, and what happens when their SMTP credentials leak.
The whole discipline fits one line: your domain's right to send mail is maintained, not owned. Every new tool spends it, every DMARC report shows the balance, and the 45 minutes a quarter you spend reading both is the cheapest insurance your invoices will ever be seen.