Steven's Knowledge

Best Practices

Production communication - deliverability, unsubscribe, observability, testing, compliance (CAN-SPAM, GDPR, CASL)

Best Practices

Email is the only kind of infrastructure your competitors can mess up to your detriment — their bad emails get your IP range banned, their spam complaints affect your shared sender pools. These habits keep your messages landing in inboxes.

Deliverability Fundamentals

Deliverability is the % of your sent emails that reach the inbox (not spam, not bounced). The factors:

FactorWhat helps
Domain authenticationSPF + DKIM + DMARC all set correctly
IP reputationDedicated IP for high volume; warm up gradually
Sender reputationLow bounce + low complaint + high engagement
List hygieneDon't send to bounces, unsubscribers, complaints
ContentAvoid spammy words, balanced text/HTML ratio, no broken images
FrequencySudden bursts look like spam attacks
Engagement signalsOpens, clicks, replies all help; ignores / deletes hurt

The hierarchy: transactional emails for users who explicitly created accounts > marketing to engaged users > marketing to cold lists. Each step down is harder.

SPF / DKIM / DMARC

Mandatory in 2025+. Gmail and Yahoo now enforce them — emails without all three risk going straight to spam.

example.com    TXT    "v=spf1 include:_spf.resend.com -all"
resend._domainkey.example.com    TXT    "v=DKIM1; k=rsa; p=..."
_dmarc.example.com    TXT    "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100"

-all (hard fail) > ~all (soft fail). p=reject > p=quarantine > p=none. Aim for hard SPF and DMARC reject once you're confident your sending sources are all authorized.

Dedicated IP

For >100K emails/month, consider a dedicated IP on your transactional provider. Pros: your reputation, your control. Cons: must warm up, smaller volumes can be a disadvantage (no other senders to share warming signal).

Below 100K/month: stay on the shared IP pool. The provider warmed it for everyone; you benefit.

Unsubscribe (Required, Honor Always)

For any non-transactional email:

  • One-click unsubscribe in every send (Gmail/Yahoo requirement: List-Unsubscribe header + visible footer link).
  • Honor immediately, not "within 10 days." (CAN-SPAM says 10 days; in practice make it instant.)
  • No requirement to log in to unsubscribe. That's hostile and illegal in some jurisdictions.
  • Confirm unsubscribe with a brief landing page, no further sign-in required.
  • Suppress globally, not just per-list. A user who unsubscribed from your marketing emails should not be added to a different marketing list later without re-consent.
// One-click unsubscribe header
'List-Unsubscribe': '<https://example.com/u/abc123>, <mailto:unsubscribe+abc123@example.com>'
'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click'

The HTTP POST to your unsubscribe URL doesn't need authentication — the link itself is the token. Verify the token, suppress, done.

For transactional emails (password reset, receipts), unsubscribe is generally not required, but always include "account preferences" links so users can manage what they receive.

Suppression Lists

Two lists every system needs:

ListSourceEffect
Hard bouncesWebhook: invalid addressNever email this address again
ComplaintsWebhook: marked as spamNever email this address again
UnsubscribesWebhook or user actionDon't send marketing; transactional OK
Manual blocksSupport / abuse teamPer their request

Before every send: check the suppression list. Don't trust your providers to enforce it — they sometimes have gaps.

async function sendEmail(to, ...) {
  if (await suppressions.includes(to)) {
    metrics.increment('email.suppressed');
    return;
  }
  await provider.send({ to, ... });
}

Observability

MetricWhy
Send rateVolume; alert on spikes (could be bug or abuse)
Delivery rate(delivered / sent); should be >99%
Bounce rateHard bounces; >2% is bad
Complaint rateSpam reports; >0.1% triggers Gmail's spam filter on you
Open rateSoft signal of engagement (limited by Apple Mail Privacy Protection)
Click-through rateBetter engagement signal
Unsubscribe rate per campaignHigh = bad targeting
Time to deliverySlow = provider queue issues

Most providers ship a dashboard. Mirror critical metrics to your own observability (Prometheus & Grafana) so you can alert on them like any other system.

Set up a DMARC aggregate report parser_dmarc reports tell you who's sending email claiming to be you. Useful for spotting unauthorized senders.

Testing

Three layers:

Local Development

Use Mailtrap or Mailpit — a fake SMTP server that catches outgoing emails without sending them:

# docker-compose.yml
services:
  mailpit:
    image: axllent/mailpit
    ports:
      - "1025:1025"   # SMTP
      - "8025:8025"   # web UI

Point your dev environment at port 1025; emails land in the web UI at port 8025. Devs see exactly what users see, no real send.

CI

Render templates, snapshot the HTML, compare. Catches accidental layout breakage.

test('welcome email renders correctly', () => {
  const html = render(<WelcomeEmail name="Alice" />);
  expect(html).toMatchSnapshot();
});

Pre-Production

Send to a real mailbox you control via the provider's test API key or sandbox mode. Validates the actual send pipeline without spamming real users.

Email Client Compatibility

The bad news: email clients vary wildly. Gmail's renderer ≠ Outlook's ≠ Apple Mail's.

  • Outlook desktop uses Word's renderer — supports almost nothing modern. Tables, inline styles, ancient HTML.
  • Gmail strips <style> tags in some contexts — use inline styles.
  • Apple Mail is the most modern; dark mode aware.
  • Mobile clients are most varied; many users now use Gmail mobile.

Use Litmus or Email on Acid to preview across 50+ clients before launch.

For most teams, React Email + a careful template is fine — it abstracts the worst quirks. Test the critical templates in 3-5 representative clients.

Compliance

LawApplies toKey requirements
CAN-SPAM (US)Commercial emailHonest from, accurate subject, physical address, unsubscribe within 10 days
GDPR (EU)Personal data of EU residentsLawful basis (consent for marketing), data access, deletion
CASL (Canada)Commercial email to CanadiansExpress consent (opt-in), identification, unsubscribe
PECR (UK)Marketing communicationsConsent, identification

In practice:

  • Marketing: require explicit opt-in. No pre-checked boxes. Track when and how they opted in.
  • Transactional: implicit consent from the account relationship is generally fine.
  • Cold outreach: B2B may be OK in CAN-SPAM; usually requires consent in EU.
  • Cookie-banners aren't enough for email consent (separate consent).

Keep audit trails: who opted in, when, from which form. Required for GDPR Article 7.

Operational Habits

HabitWhy
Send via a queue, not synchronouslyProvider hiccups don't break user flows
Different sending domains for transactional vs marketingInsulate reputation
Idempotency keys on sendCrashing mid-loop doesn't double-send
Rate limiting your own send rateAvoid sudden bursts
Reply-To to a monitored addressUsers will reply; respond or auto-respond
Test unsubscribe end-to-end monthlyBugs here are reputation-damaging
Monitor your own DMARC reportsSpot impersonators and bad config

Common Pitfalls

PitfallSymptomFix
From: noreply@example.comReplies go nowhereUse a monitored mailbox or Reply-To
Sending from @gmail.com / @yahoo.comStrict DMARC at those providers rejects youUse your own verified domain
Embedding tracking pixels in transactional emailPrivacy concerns; some providers warn usersDon't track transactional sends
Showing user-supplied content (subject, body) unsanitizedPhishing-by-proxy through your serviceValidate and constrain user-supplied fields
Sending to typo addresses (gmial.com)Hard bounces accumulateValidate the email format; use email validation services
All emails from the same template variablePersonalization opportunities missedUse templates with conditional sections
No unsubscribe link on "newsletters"Legal risk + complaintsAlways include
Same content as last weekFrequency fatigueVary content; segment lists
Big images, no alt textBlocked images render as nothingAlways provide alt

Checklist

Production communication checklist

  • SPF, DKIM, DMARC configured; DMARC at p=reject
  • Separate sending domains for transactional vs marketing
  • Transactional emails sent via a job queue, not synchronously
  • React Email (or equivalent) for templates; versioned in code
  • Localization for non-English audiences
  • One-click List-Unsubscribe header on all non-transactional emails
  • Suppression list checked before every send
  • Webhook handler for bounces, complaints, unsubscribes
  • Webhook signature verified
  • Mailtrap / Mailpit in development environments
  • Snapshot tests for critical email templates
  • Pre-production sends to test mailbox before launch
  • Metrics: delivery rate, bounce rate, complaint rate alerting
  • DMARC aggregate reports monitored
  • Unsubscribe flow tested end-to-end monthly
  • Compliance documentation (consent capture, retention)
  • Reply-To monitored or auto-responded to
  • Rate limiting on send to prevent bursts
  • Backup provider configured (failover when primary is down)

On this page