<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://lalitkumarjangid.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 08 Nov 2026 10:34:41 GMT</lastBuildDate><atom:link href="https://lalitkumarjangid.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Best Amazon SES Alternatives in 2026]]></title><description><![CDATA[Ten Amazon SES alternatives compared on price, free tier, SMTP, webhooks, deliverability and campaigns, with SES pricing explained.]]></description><link>https://lalitkumarjangid.hashnode.dev/best-amazon-ses-alternatives</link><guid isPermaLink="true">https://lalitkumarjangid.hashnode.dev/best-amazon-ses-alternatives</guid><category><![CDATA[AWS]]></category><category><![CDATA[email]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[SaaS]]></category><dc:creator><![CDATA[Lalit Kumar Jangid]]></dc:creator><pubDate>Sun, 08 Nov 2026 05:50:39 GMT</pubDate><content:encoded><![CDATA[<p>Amazon SES is built for sending at scale from inside AWS, and many teams start there. The <strong>best Amazon SES alternatives</strong> are for when you want more around the send: no sandbox approval, a dashboard with logs, templates you can edit without a deploy, delivery events without wiring up Amazon SNS, and marketing email in the same place. This guide compares ten Amazon SES (AWS SES) alternatives on price, free tier, SMTP, webhooks, deliverability and campaigns, using each vendor's own pricing and product pages, checked between October 27 and November 8, 2026.</p>
<p><em>We make Cresca, so it is listed first. Every other entry is described from the vendor's own public pages, without ranking claims about them. Prices and plans change, so confirm on each vendor's site before you switch.</em></p>
<p><strong>TL;DR</strong></p>
<ul>
<li>New SES accounts start in a sandbox: verified recipients only, 200 messages per 24 hours, 1 per second, until AWS grants production access.</li>
<li>Cresca: a transactional email API and AI-designed marketing campaigns on one plan, from $29/month, with no sandbox.</li>
<li>Most alternatives include a dashboard, logs and webhooks out of the box; check SMTP, free tiers and how marketing email is billed.</li>
<li>Still moving off Amazon Pinpoint after its October 30, 2026 end of support? See the <a href="https://www.cresca.xyz/blog/amazon-pinpoint-alternative">Pinpoint migration guide</a>.</li>
</ul>
<p><strong>Quick picks</strong></p>
<ul>
<li><strong>App email and marketing campaigns on one plan:</strong> Cresca, from $29/month, no sandbox.</li>
<li><strong>Largest free monthly allowance in this list:</strong> Mailtrap (4,000 emails a month) and Resend (3,000 a month).</li>
<li><strong>Lowest paid entry price:</strong> MailerSend at $7/month for 5,000 emails, then Brevo at $9/month from 5,000 emails.</li>
<li><strong>SMTP relay first:</strong> SMTP2GO, Mailgun and Postmark all offer SMTP next to their APIs.</li>
</ul>
<h2>What is Amazon SES?</h2>
<p>Amazon Simple Email Service (Amazon SES, often called AWS SES) is the email sending service inside Amazon Web Services. You send through its API or SMTP interface, pay per email, and build the rest yourself: event handling through other AWS services, templates, a log your support team can read, and any campaign tooling. That trade is what makes SES cheap per email, and it is why teams look for an Amazon SES alternative once they want those parts ready-made.</p>
<h2>Why teams look for an Amazon SES alternative</h2>
<ul>
<li><strong>The sandbox.</strong> AWS places all new accounts in the SES sandbox, where you can only send to verified addresses and domains, up to 200 messages per 24 hours and 1 per second. Leaving it means requesting production access; AWS says its support team gives an initial response within 96 hours.</li>
<li><strong>Plumbing for events.</strong> Deliveries, bounces, complaints, opens and clicks are published as events to Amazon SNS, EventBridge, CloudWatch or Data Firehose, which you configure and consume yourself.</li>
<li><strong>Pricing plans.</strong> New SES accounts start on the Essentials plan at $0.16 per 1,000 emails; Pro and Enterprise plans add fixed monthly charges per account and region. The full breakdown is below.</li>
<li><strong>No campaign tools.</strong> SES sends marketing email, but its pages describe no campaign builder, so newsletters need another tool on top.</li>
<li><strong>Amazon Pinpoint's end of support</strong> on October 30, 2026 left teams that used Pinpoint for email campaigns looking for a new home for contacts, templates and campaigns.</li>
</ul>
<h2>Amazon SES pricing: what you actually pay</h2>
<p>Amazon SES pricing is per email, with extras for attachments, dedicated IPs and deliverability tools. Figures from the Amazon SES pricing page, checked on November 8, 2026, for the first 10 million emails a month:</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Per 1,000 emails</th>
<th>Fixed monthly fee</th>
</tr>
</thead>
<tbody><tr>
<td><strong>À la carte</strong></td>
<td>$0.10</td>
<td>None</td>
</tr>
<tr>
<td><strong>Essentials plan</strong></td>
<td>$0.16</td>
<td>None</td>
</tr>
<tr>
<td><strong>Pro plan</strong></td>
<td>$0.22</td>
<td>$105 per account per region</td>
</tr>
<tr>
<td><strong>Enterprise plan</strong></td>
<td>$0.23</td>
<td>$500 per account per region</td>
</tr>
</tbody></table>
<ul>
<li><strong>Which rate applies:</strong> AWS says accounts with no metered SES activity since June 1, 2025 start on the Essentials plan from July 21, 2026.</li>
<li><strong>Attachments:</strong> $0.12 per GB of attachment data sent.</li>
<li><strong>Dedicated IPs:</strong> $24.95 per IP per month (standard), or managed dedicated IPs at $15 per account per month plus $0.08 per 1,000 emails.</li>
<li><strong>Virtual Deliverability Manager:</strong> $0.07 per 1,000 emails for SES deliverability insights.</li>
<li><strong>Free tier:</strong> new AWS customers get up to $200 in AWS Free Tier credits that can be used on SES.</li>
</ul>
<p>At 10,000 emails a month, that is about $1.00 à la carte or $1.60 on Essentials, and $26.60 if you add one standard dedicated IP. The per-email price is rarely the reason teams switch. The cost is the work around it: the sandbox request, wiring delivery events through Amazon SNS or EventBridge, a template workflow, and a place where support can see what happened to an email.</p>
<h2>How we compared these Amazon SES alternatives</h2>
<p>Each service is described from its own pricing pages and documentation, not from third-party reviews. We looked at:</p>
<ul>
<li><strong>Setup:</strong> whether you can send to real recipients on day one, or wait for an approval step like the SES sandbox.</li>
<li><strong>Price:</strong> the free option and the cheapest paid plan, in US dollars per month.</li>
<li><strong>Sending options:</strong> HTTP API, SMTP relay and delivery webhooks.</li>
<li><strong>Deliverability:</strong> domain authentication (SPF, DKIM, DMARC) and how bounces and complaints are handled.</li>
<li><strong>Marketing email:</strong> whether campaigns live in the same account and plan, or in a separate product.</li>
</ul>
<h2>Best Amazon SES alternatives compared (2026)</h2>
<table>
<thead>
<tr>
<th>Service</th>
<th>Best for</th>
<th>Free option</th>
<th>Paid from</th>
<th>SMTP relay</th>
<th>Webhooks</th>
<th>Marketing email</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Cresca</strong></td>
<td>App email and AI-designed marketing campaigns in one account</td>
<td>30 days free, 1,000 emails, no credit card</td>
<td>$29/month: 7,500 emails and 5,000 contacts, campaigns included</td>
<td>On the roadmap</td>
<td>On the roadmap</td>
<td>Yes, on the same plan</td>
</tr>
<tr>
<td><strong>Resend</strong></td>
<td>Developers; sends emails built with React Email</td>
<td>Free plan: 3,000 emails/month, 100 per day</td>
<td>$20/month for 50,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Separate marketing plans priced by contacts</td>
</tr>
<tr>
<td><strong>Postmark</strong></td>
<td>Transactional email with separate message streams</td>
<td>100 emails/month developer plan</td>
<td>$15/month for 10,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Broadcast message streams</td>
</tr>
<tr>
<td><strong>SendGrid</strong></td>
<td>Email API at scale, part of Twilio</td>
<td>60-day free trial, 100 emails/day</td>
<td>Essentials from $19.95/month</td>
<td>Yes</td>
<td>Yes</td>
<td>Marketing Campaigns, sold as a separate plan</td>
</tr>
<tr>
<td><strong>Mailgun</strong></td>
<td>Developers; email API, SMTP and email validation</td>
<td>Free plan: 100 emails/day</td>
<td>$15/month for 10,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Not stated on its pricing page</td>
</tr>
<tr>
<td><strong>MailerSend</strong></td>
<td>Email, SMS and WhatsApp for apps</td>
<td>Free plan: 500 emails/month</td>
<td>$7/month for 5,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Not stated; bulk emailing on paid plans</td>
</tr>
<tr>
<td><strong>Mailtrap</strong></td>
<td>Developer and product teams; sending plus a testing sandbox</td>
<td>Free plan: 4,000 emails/month, 150 per day</td>
<td>$15/month for 10,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Email Marketing, sold separately</td>
</tr>
<tr>
<td><strong>Mailchimp Transactional</strong></td>
<td>Mailchimp customers adding app email</td>
<td>Up to 500 free sends to a verified domain</td>
<td>$20 per block of 25,000 emails, plus a Mailchimp Standard or Premium plan</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes, through the Mailchimp plan it is added to</td>
</tr>
<tr>
<td><strong>Brevo</strong></td>
<td>Marketing campaigns, automation and transactional email in one account</td>
<td>Free plan</td>
<td>Starter $9/month from 5,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes, in the same account</td>
</tr>
<tr>
<td><strong>SMTP2GO</strong></td>
<td>SMTP relay and email API, with SMS</td>
<td>Free plan: 1,000 emails/month</td>
<td>$10/month for 10,000 emails</td>
<td>Yes</td>
<td>Yes</td>
<td>Not stated on its pricing page</td>
</tr>
</tbody></table>
<p><em>Based on each vendor's public pricing and product pages, checked on October 27, 2026 (Brevo and SMTP2GO on November 8, 2026). Prices in US dollars, billed monthly where both options are shown.</em></p>
<h2>1. Cresca: SES-level sending without the setup, plus campaigns</h2>
<p>Cresca is a transactional email service and an AI email marketing platform in one account. Verify your domain, create an API key and send: there is no sandbox to leave, and the dashboard shows a timeline for every email. See <a href="https://www.cresca.xyz/transactional-email">Cresca transactional email</a>.</p>
<ul>
<li><strong>API:</strong> <code>POST /emails</code> for one email to up to 50 recipients, batches of up to 100, scheduling up to 30 days ahead, attachments, tags and <code>Idempotency-Key</code> headers for safe retries.</li>
<li><strong>Templates:</strong> Design in a template editor, publish, and send by alias with variables. Every published version is kept.</li>
<li><strong>Marketing:</strong> AI-designed campaigns, contact lists, scheduling and campaign reports on the same plan and the same verified domain.</li>
<li><strong>Pricing:</strong> 30 days free with 1,000 emails and no credit card. Professional is $29/month for 7,500 emails and 5,000 contacts, covering API email and campaigns.</li>
<li><strong>On the roadmap:</strong> Outbound webhooks and an SMTP relay. Today you read each email's status from the API or the dashboard.</li>
</ul>
<h2>2. Resend</h2>
<p>Resend presents itself as an email API for developers and highlights emails built with React Email.</p>
<ul>
<li><strong>Free option:</strong> 3,000 emails per month, up to 100 per day.</li>
<li><strong>Paid:</strong> Pro is $20/month for 50,000 emails.</li>
<li><strong>Sending:</strong> REST API, SMTP relay, SDKs and webhooks on all plans.</li>
<li><strong>Marketing:</strong> Separate marketing plans priced by contacts.</li>
</ul>
<h2>3. Postmark</h2>
<p>Postmark describes itself as a transactional email service, with transactional and broadcast email kept in separate message streams.</p>
<ul>
<li><strong>Free option:</strong> A developer plan with 100 emails per month.</li>
<li><strong>Paid:</strong> Basic is $15/month for 10,000 emails.</li>
<li><strong>Sending:</strong> Email API, SMTP, event webhooks and inbound processing.</li>
<li><strong>Marketing:</strong> Broadcast message streams in the same account.</li>
</ul>
<h2>4. SendGrid</h2>
<p>SendGrid, part of Twilio, sells its Email API and Marketing Campaigns as separate products.</p>
<ul>
<li><strong>Free option:</strong> A 60-day free trial with 100 emails per day.</li>
<li><strong>Paid:</strong> Email API Essentials starts at $19.95/month.</li>
<li><strong>Sending:</strong> API and SMTP, with event webhooks on paid plans.</li>
<li><strong>Marketing:</strong> Marketing Campaigns, purchased as a separate plan.</li>
</ul>
<h2>5. Mailgun</h2>
<p>Mailgun calls itself a transactional email delivery service and API for developers.</p>
<ul>
<li><strong>Free option:</strong> 100 emails per day.</li>
<li><strong>Paid:</strong> Basic starts at $15/month for 10,000 emails.</li>
<li><strong>Sending:</strong> RESTful APIs and SMTP relay, with webhooks.</li>
<li><strong>Marketing:</strong> Not stated on its pricing page.</li>
</ul>
<h2>6. MailerSend</h2>
<p>MailerSend presents itself as a team-friendly email API for apps, with SMS and WhatsApp alongside email.</p>
<ul>
<li><strong>Free option:</strong> 500 emails per month.</li>
<li><strong>Paid:</strong> Hobby is $7/month for 5,000 emails.</li>
<li><strong>Sending:</strong> Email API, SMTP relay and webhooks.</li>
<li><strong>Marketing:</strong> No separate marketing product described; bulk emailing on paid plans.</li>
</ul>
<h2>7. Mailtrap</h2>
<p>Mailtrap offers email sending for developer and product teams, with email marketing and a testing sandbox as separate products.</p>
<ul>
<li><strong>Free option:</strong> 4,000 emails per month, up to 150 per day.</li>
<li><strong>Paid:</strong> Basic is $15/month for 10,000 emails.</li>
<li><strong>Sending:</strong> API, SMTP relay and webhooks.</li>
<li><strong>Marketing:</strong> Email Marketing, sold separately.</li>
</ul>
<h2>8. Mailchimp Transactional (formerly Mandrill)</h2>
<p>Mailchimp Transactional is sold as an add-on to a Mailchimp plan.</p>
<ul>
<li><strong>Free option:</strong> Up to 500 free emails to a verified domain for new users.</li>
<li><strong>Paid:</strong> $20 per block of 25,000 emails, plus a Mailchimp Standard or Premium plan.</li>
<li><strong>Sending:</strong> API, SMTP integration and webhooks.</li>
<li><strong>Marketing:</strong> Through the Mailchimp plan it is added to.</li>
</ul>
<h2>9. Brevo</h2>
<p>Brevo sells email marketing, automation and transactional email in one account, alongside SMS and other channels.</p>
<ul>
<li><strong>Free option:</strong> A free plan, with no credit card needed.</li>
<li><strong>Paid:</strong> Starter is $9/month from 5,000 emails a month.</li>
<li><strong>Sending:</strong> SMTP relay and API keys for transactional email, with transactional webhooks.</li>
<li><strong>Marketing:</strong> Campaigns, templates and segmentation on the same plans; automation from the Standard plan.</li>
</ul>
<h2>10. SMTP2GO</h2>
<p>SMTP2GO describes itself as an email and SMS delivery service that you connect through SMTP or its API.</p>
<ul>
<li><strong>Free option:</strong> Up to 1,000 emails a month.</li>
<li><strong>Paid:</strong> Starter is $10/month for 10,000 emails, with extra emails at $1 per thousand.</li>
<li><strong>Sending:</strong> SMTP relay and HTTP API, with webhooks and reporting.</li>
<li><strong>Marketing:</strong> Not stated on its pricing page.</li>
</ul>
<h2>Deliverability: what changes when you leave Amazon SES</h2>
<p>Switching providers does not reset your domain's reputation, but it does change who signs and sends your mail. Plan for these:</p>
<ul>
<li><strong>Authentication records.</strong> Add the new provider's DKIM records and, where it uses a custom MAIL FROM domain, its SPF record. Keep your DMARC record; a domain can only have one.</li>
<li><strong>Shared or dedicated IPs.</strong> Most plans in this list send from shared IPs. A dedicated IP needs steady volume and a warm-up period before it helps.</li>
<li><strong>Bounces and complaints.</strong> Carry your SES suppression list over, so addresses that bounced or complained are not mailed again from the new provider.</li>
<li><strong>Gradual moves.</strong> Switch one email type at a time and watch bounce and complaint rates before moving the next.</li>
</ul>
<p>In Cresca, domain setup shows the DKIM and SPF records to publish and checks whether your domain has a DMARC record. Hard bounces, repeated soft bounces, complaints and unsubscribes are suppressed automatically, for API email and campaigns alike. See the <a href="https://www.cresca.xyz/blog/email-deliverability-complete-guide">email deliverability guide</a> for the full checklist.</p>
<h2>Moving from Amazon SES to Cresca</h2>
<ol>
<li><strong>Verify your sending domain</strong> in Cresca by publishing the DNS records it shows, and keep SES sending while you switch. See the <a href="https://www.cresca.xyz/docs/quickstart">quickstart</a>.</li>
<li><strong>Create a sending-access API key</strong> and store it as <code>CRESCA_API_KEY</code>.</li>
<li><strong>Move templates.</strong> Paste your SES template HTML into Cresca's template editor with Import HTML, mark variables with triple braces and publish.</li>
<li><strong>Swap the send call</strong>, one email type at a time, starting with a low-risk one such as a welcome email.</li>
<li><strong>Keep a list of addresses that bounced or complained on SES</strong> and leave them out of your Cresca sends, so your new domain setup starts with a clean reputation.</li>
<li><strong>Switch the rest</strong> once the dashboard timeline looks right, then retire the SES configuration.</li>
</ol>
<p>Here is the same email with the AWS SDK for JavaScript (SESv2) and with Cresca:</p>
<pre><code class="language-js">// Before: Amazon SES with the AWS SDK for JavaScript v3
import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2';

const ses = new SESv2Client({ region: 'us-east-1' });

await ses.send(
  new SendEmailCommand({
    FromEmailAddress: 'Acme &lt;hello@acme.com&gt;',
    Destination: { ToAddresses: ['ana@example.com'] },
    Content: {
      Simple: {
        Subject: { Data: 'Welcome to Acme' },
        Body: { Html: { Data: '&lt;p&gt;Hi Ana, your account is ready.&lt;/p&gt;' } },
      },
    },
  }),
);
</code></pre>
<pre><code class="language-js">// After: Cresca, with fetch (Node.js 18+)
const res = await fetch('https://api.cresca.xyz/api/v1/emails', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CRESCA_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'welcome/user-123',
  },
  body: JSON.stringify({
    from: 'Acme &lt;hello@acme.com&gt;',
    to: 'ana@example.com',
    subject: 'Welcome to Acme',
    html: '&lt;p&gt;Hi Ana, your account is ready.&lt;/p&gt;',
  }),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.name}: ${body.message}`);
</code></pre>
<p>Full guides for your stack: <a href="https://www.cresca.xyz/blog/send-email-nodejs">Node.js</a>, <a href="https://www.cresca.xyz/blog/send-email-python">Python</a>, <a href="https://www.cresca.xyz/blog/send-email-java">Java</a>, <a href="https://www.cresca.xyz/blog/send-email-golang">Go</a>, <a href="https://www.cresca.xyz/blog/send-email-php">PHP</a> and more. Comparing transactional providers more broadly? See the <a href="https://www.cresca.xyz/blog/best-transactional-email-services">best transactional email services</a>.</p>
<h2>Frequently asked questions</h2>
<h3>What is the best Amazon SES alternative?</h3>
<p>It depends on what you need around sending. If you also send newsletters and campaigns, Cresca puts a transactional email API and AI-designed marketing email on one plan, with no sandbox and a dashboard for every email. Resend, Postmark, SendGrid, Mailgun, MailerSend, Mailtrap, Mailchimp Transactional and SMTP2GO focus on sending, and Brevo combines marketing with transactional email.</p>
<h3>Is there a cheaper alternative to Amazon SES?</h3>
<p>Per email, rarely. Amazon SES costs $0.10 per 1,000 emails à la carte or $0.16 on the Essentials plan, which is less per email than the paid plans in this list. Alternatives charge more per email but include the dashboard, logs, templates, delivery events and support that you would otherwise build or buy around SES. Several also have free plans, from 1,000 emails a month on SMTP2GO to 4,000 on Mailtrap.</p>
<h3>How long does it take to get out of the Amazon SES sandbox?</h3>
<p>You request production access from the SES console or the AWS CLI, giving your use case and website. AWS says its support team provides an initial response within 96 hours. Until then you can only send to verified addresses, up to 200 messages per 24 hours.</p>
<h3>Is Amazon SES affected by the Amazon Pinpoint end of support?</h3>
<p>No. Amazon Pinpoint's engagement features ended on October 30, 2026, but Amazon SES continues. Teams that used Pinpoint for email campaigns, segments and journeys need another place for them, which is what the Pinpoint migration guide covers.</p>
<h3>Can I keep my domain authentication when I leave SES?</h3>
<p>You keep your domain, but each provider signs mail with its own DKIM keys, so you add the new provider's DNS records. DKIM records for different providers can sit side by side, which lets you move one email type at a time and keep SES running until the switch is complete.</p>
<h3>Do SES alternatives support SMTP?</h3>
<p>Most of the services in this comparison offer an SMTP relay as well as an HTTP API. Cresca sends through its HTTP API today, and an SMTP relay is on its roadmap.</p>
<h2>Try Cresca</h2>
<p>Send your app's email and your campaigns from one account, with no sandbox. <strong><a href="https://app.cresca.xyz/signup">Try Cresca free for 30 days</a></strong>, no credit card required, then follow the <a href="https://www.cresca.xyz/docs/quickstart">quickstart</a>.</p>
]]></content:encoded></item><item><title><![CDATA[I checked the DMARC records of the top 10,000 domains. Only 61% enforce it]]></title><description><![CDATA[A DNS scan of SPF, DMARC, BIMI and MTA-STS across the top 10,000 domains: the method in Node, the parsing traps and the results.]]></description><link>https://lalitkumarjangid.hashnode.dev/dmarc-adoption-top-10000-domains</link><guid isPermaLink="true">https://lalitkumarjangid.hashnode.dev/dmarc-adoption-top-10000-domains</guid><category><![CDATA[email]]></category><category><![CDATA[email security]]></category><category><![CDATA[dns]]></category><category><![CDATA[Security]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Lalit Kumar Jangid]]></dc:creator><pubDate>Sat, 07 Nov 2026 16:10:38 GMT</pubDate><content:encoded><![CDATA[<p>Since 2024, Gmail and Yahoo have required bulk senders to publish a DMARC record. So I wanted to know how far the most popular domains on the internet have actually got. Do they publish DMARC? Do they enforce it, or just monitor? And how many have moved on to BIMI and MTA-STS?</p>
<p>On November 6, 2026 I looked up the public DNS records of the top 10,000 domains on the Tranco list, a research ranking of popular sites that is built to be hard to game. No email was sent and no website was fetched: these are only DNS lookups, the same ones any mail server makes.</p>
<p>The short version:</p>
<table>
<thead>
<tr>
<th>Of the 7,236 top domains that receive email</th>
<th>Share</th>
</tr>
</thead>
<tbody><tr>
<td>Publish a valid DMARC record</td>
<td>82.8%</td>
</tr>
<tr>
<td>Enforce it (p=quarantine or p=reject)</td>
<td>61.2%</td>
</tr>
<tr>
<td>Use p=reject</td>
<td>35.1%</td>
</tr>
<tr>
<td>Publish exactly one SPF record</td>
<td>92.7%</td>
</tr>
<tr>
<td>Publish a BIMI record</td>
<td>13.3%</td>
</tr>
<tr>
<td>Publish an MTA-STS record</td>
<td>4.0%</td>
</tr>
</tbody></table>
<p>The rest of this post covers how the scan works, the parsing traps I hit, what stood out in the results, and how to check your own domain in a minute.</p>
<h2>The method</h2>
<p><strong>The domains.</strong> The Tranco top 10,000 (list ID K9YYW, created November 5, 2026). One entry wasn't a valid hostname and was skipped.</p>
<p><strong>The lookups.</strong> For each domain, six DNS queries:</p>
<table>
<thead>
<tr>
<th>Record</th>
<th>Name queried</th>
<th>What it tells you</th>
</tr>
</thead>
<tbody><tr>
<td>MX</td>
<td><code>example.com</code></td>
<td>Whether the domain receives email at all</td>
</tr>
<tr>
<td>SPF</td>
<td>TXT at <code>example.com</code></td>
<td>Which servers may send for it</td>
</tr>
<tr>
<td>DMARC</td>
<td>TXT at <code>_dmarc.example.com</code></td>
<td>What receivers should do with mail that fails</td>
</tr>
<tr>
<td>BIMI</td>
<td>TXT at <code>default._bimi.example.com</code></td>
<td>A brand logo for supporting inboxes</td>
</tr>
<tr>
<td>MTA-STS</td>
<td>TXT at <code>_mta-sts.example.com</code></td>
<td>A policy asking senders to use verified TLS</td>
</tr>
<tr>
<td>TLS-RPT</td>
<td>TXT at <code>_smtp._tls.example.com</code></td>
<td>Where to send TLS failure reports</td>
</tr>
</tbody></table>
<p><strong>The resolvers.</strong> Cloudflare (1.1.1.1) and Google (8.8.8.8), set explicitly so the result doesn't depend on my ISP's resolver.</p>
<p><strong>The denominator.</strong> Percentages are of domains with at least one real MX record, because a DMARC policy matters most for domains that actually handle email. Of the 9,960 domains analysed, 7,236 have an MX record. The other 2,724 get their own section below.</p>
<p>Here is the core of the scanner, using only Node's built-in <code>dns</code> module:</p>
<pre><code class="language-js">import { Resolver } from "node:dns/promises";

const resolver = new Resolver({ timeout: 4000, tries: 3 });
resolver.setServers(["1.1.1.1", "8.8.8.8"]);

// "No such record" is an answer. A timeout or SERVFAIL is not.
const MISSING = new Set(["ENOTFOUND", "ENODATA"]);

async function lookup(kind, name) {
  try {
    const value = kind === "mx" ? await resolver.resolveMx(name) : await resolver.resolveTxt(name);
    return { ok: true, value };
  } catch (err) {
    if (MISSING.has(err.code)) return { ok: true, value: [] };
    return { ok: false, code: err.code };
  }
}

// A TXT record can be split into 255-byte strings. Join them before parsing.
const records = (txt, prefix) =&gt;
  txt.map((chunks) =&gt; chunks.join("")).filter((t) =&gt; t.trim().toLowerCase().startsWith(prefix));

function tags(record) {
  const out = {};
  for (const part of record.split(";")) {
    const i = part.indexOf("=");
    if (i &gt; 0) out[part.slice(0, i).trim().toLowerCase()] = part.slice(i + 1).trim();
  }
  return out;
}

async function scan(domain) {
  const [mx, apex, dmarc] = await Promise.all([
    lookup("mx", domain),
    lookup("txt", domain),
    lookup("txt", `_dmarc.${domain}`),
  ]);
  const failed = [mx, apex, dmarc].find((r) =&gt; !r.ok);
  if (failed) return { domain, err: failed.code }; // excluded, not counted as "missing"

  const spf = records(apex.value, "v=spf1");
  const dm = records(dmarc.value, "v=dmarc1");
  return {
    domain,
    mx: mx.value.length &gt; 0,
    spfCount: spf.length,           // more than 1 = SPF permerror
    dmarcCount: dm.length,          // more than 1 = invalid
    policy: dm.length === 1 ? (tags(dm[0]).p || "").toLowerCase() : null,
  };
}
</code></pre>
<p>The full version adds BIMI, MTA-STS and TLS-RPT, RFC 7505 null MX detection and the SPF <code>all</code> qualifier. It runs 40 domains at a time and retries failures once at the end. All 10,000 domains took under four minutes.</p>
<h2>Five traps worth knowing if you parse these records yourself</h2>
<p><strong>1. "No record" and "lookup failed" are different answers.</strong> <code>ENOTFOUND</code> and <code>ENODATA</code> mean the record doesn't exist. <code>ESERVFAIL</code>, <code>EREFUSED</code> and timeouts mean you don't know. If you count both as "no DMARC", you overstate how many domains lack it. 39 domains still failed after a retry (32 SERVFAIL, 6 FORMERR, 1 REFUSED), and I excluded them rather than guess.</p>
<p><strong>2. TXT records come back in chunks.</strong> A long SPF or DMARC record is split into strings of up to 255 bytes, and <code>resolveTxt</code> returns each record as an array of those strings. Join them with no separator before parsing, or a long <code>include:</code> list gets cut in half.</p>
<p><strong>3. More than one SPF record is not "extra SPF".</strong> RFC 7208 says a domain with two <code>v=spf1</code> records gives a permanent error, so SPF fails for every email. 0.6% of the mail-receiving domains (46 domains) publish more than one.</p>
<p><strong>4. A domain with no MX is not the same as one that refuses mail.</strong> An RFC 7505 "null MX" (<code>0 .</code>) states that a domain accepts no email. 74 domains in the list publish one. Most domains without email simply have no MX record at all.</p>
<p><strong>5. Check your parser against a second source.</strong> I re-resolved a random sample of 40 domains through a third resolver (Quad9, 9.9.9.9), with a separate regex-based DMARC parser. The policy matched for all 40.</p>
<h2>What the results show</h2>
<h3>Most top domains publish DMARC. Far fewer enforce it.</h3>
<p>82.8% of mail-receiving domains publish a valid DMARC record, but the policy is where it gets interesting:</p>
<table>
<thead>
<tr>
<th>DMARC policy</th>
<th>Share of mail-receiving domains</th>
</tr>
</thead>
<tbody><tr>
<td>p=reject</td>
<td>35.1%</td>
</tr>
<tr>
<td>p=quarantine</td>
<td>26.1%</td>
</tr>
<tr>
<td>p=none</td>
<td>21.5%</td>
</tr>
<tr>
<td>No DMARC record</td>
<td>17.0%</td>
</tr>
</tbody></table>
<p><code>p=none</code> asks for reports but tells receivers to do nothing with failing mail, so an attacker can still put that domain in a From address. It's the right first step, and a lot of domains seem to have stayed on it.</p>
<p>The good news: 87.0% of domains with a DMARC record include a <code>rua=</code> address for aggregate reports, so most of them can see who is sending mail as their domain.</p>
<h3>Bigger sites enforce more</h3>
<table>
<thead>
<tr>
<th>Tranco rank</th>
<th>Mail-receiving domains</th>
<th>Enforcing DMARC</th>
<th>p=reject</th>
</tr>
</thead>
<tbody><tr>
<td>Top 100</td>
<td>65</td>
<td>75.4%</td>
<td>56.9%</td>
</tr>
<tr>
<td>101 to 1,000</td>
<td>623</td>
<td>74.8%</td>
<td>49.6%</td>
</tr>
<tr>
<td>1,001 to 10,000</td>
<td>6,548</td>
<td>59.8%</td>
<td>33.6%</td>
</tr>
</tbody></table>
<p>That's 74.9% for the top 1,000 combined, against 59.8% for ranks 1,001 to 10,000. Since adoption drops the further down the list you go, it's probably lower again among the millions of domains that aren't in any top list.</p>
<h3>SPF: an even split between strict and soft</h3>
<p>Of the 6,710 mail-receiving domains with exactly one SPF record, 46.6% end it with <code>-all</code> (fail mail from unlisted servers) and 47.7% with <code>~all</code> (soft fail). 2.1% use <code>?all</code>, which tells receivers nothing, and 3 domains end with <code>+all</code>, which allows any server on the internet to send as them.</p>
<h3>Top-level domains differ a lot</h3>
<p>Among top-level domains with at least 100 mail-receiving domains in the list:</p>
<table>
<thead>
<tr>
<th>TLD</th>
<th>Domains</th>
<th>Valid DMARC</th>
<th>Enforcing</th>
</tr>
</thead>
<tbody><tr>
<td>.com</td>
<td>3,655</td>
<td>84.7%</td>
<td>66.0%</td>
</tr>
<tr>
<td>.ru</td>
<td>252</td>
<td>84.9%</td>
<td>68.7%</td>
</tr>
<tr>
<td>.org</td>
<td>364</td>
<td>83.2%</td>
<td>55.8%</td>
</tr>
<tr>
<td>.io</td>
<td>157</td>
<td>77.1%</td>
<td>56.1%</td>
</tr>
<tr>
<td>.de</td>
<td>166</td>
<td>86.1%</td>
<td>50.6%</td>
</tr>
<tr>
<td>.net</td>
<td>398</td>
<td>64.1%</td>
<td>42.0%</td>
</tr>
<tr>
<td>.jp</td>
<td>163</td>
<td>82.2%</td>
<td>39.3%</td>
</tr>
<tr>
<td>.edu</td>
<td>125</td>
<td>99.2%</td>
<td>62.4%</td>
</tr>
</tbody></table>
<p>Nearly every <code>.edu</code> domain publishes DMARC, but more than a third of them (36.8%) stop at <code>p=none</code>. <code>.jp</code> is similar: a high adoption rate, with 42.9% on <code>p=none</code>.</p>
<h3>Domains that send no email are the easiest to spoof</h3>
<p>2,724 of the domains analysed have no MX record: CDNs, API hosts, asset domains, redirects. They don't send email, but that doesn't stop someone else from putting them in the From address of a phishing email.</p>
<p>The fix is two DNS records: an SPF record of <code>v=spf1 -all</code> and a DMARC record with <code>p=reject</code>. Only 16.4% of these domains have both.</p>
<h3>BIMI and MTA-STS are still early</h3>
<p>13.3% of mail-receiving domains publish a BIMI record, and 72.1% of those reference a mark certificate. MTA-STS (4.0%) and TLS-RPT (4.5%) are rare, even in the top 10,000.</p>
<h2>Check your own domain in a minute</h2>
<pre><code class="language-bash">D=example.com

dig +short MX $D                       # do you receive mail?
dig +short TXT $D | grep -i spf1       # exactly one line, please
dig +short TXT _dmarc.$D               # p=none, quarantine or reject?
dig +short TXT default._bimi.$D        # optional: BIMI
dig +short TXT _mta-sts.$D             # optional: MTA-STS
</code></pre>
<p>If you're not yet at <code>p=reject</code>, the usual path is:</p>
<ol>
<li>One SPF record that lists every service that sends for your domain.</li>
<li>DKIM signing on your own domain, so it aligns with your From address.</li>
<li>DMARC with <code>p=none</code> and a <code>rua=</code> address. Read the reports for a few weeks.</li>
<li>When every legitimate sender passes, move to <code>p=quarantine</code>, then <code>p=reject</code>.</li>
<li>For every domain you own that sends no email: <code>v=spf1 -all</code> and DMARC <code>p=reject</code>.</li>
</ol>
<h2>Limitations</h2>
<ul>
<li>It's one snapshot of public DNS from one location. Records change.</li>
<li>It checks records, not mail. It can't tell whether a domain's email actually passes, and DKIM keys can't be found without knowing each selector.</li>
<li>DMARC was read at the listed domain only. Subdomain policies (<code>sp=</code>) aren't analysed.</li>
<li>BIMI was checked at the <code>default</code> selector only, and MTA-STS policy files weren't fetched.</li>
<li>The top 10,000 are popular websites, not a random sample of all senders.</li>
</ul>
<hr />
<p><em>The full study, with every table, the methodology, a link for each finding and a CSV of the aggregate numbers, is on the Cresca site: <a href="https://www.cresca.xyz/research/email-authentication">DMARC adoption in 2026</a>. Cresca is the email platform I'm building, and it walks you through SPF and DKIM for your own sending domain. If you'd like a breakdown I didn't include, ask in the comments and I'll run it against the same data.</em></p>
]]></content:encoded></item></channel></rss>