Resend vs Postmark: cheap per-message plans against flat tiers
Postmark sells its first 10,000 emails for $15, which is $1.50 per 1,000 (15 ÷ 10), and its free plan stops at 100 emails a month. Resend's free plan allows 3,000 a month (100 a day) and its $20 Pro plan covers 50,000, or $0.40 per 1,000 (20 ÷ 50). So Resend is free below 3,000 emails, Postmark is $5 cheaper at exactly 10,000, and from 50,000 upward Resend wins by a wide margin: $20 against $55 on Postmark Basic. What Postmark gives back is history and structure: 45 days of activity on Basic and separate transactional and broadcast streams. Resend gives you signed webhooks, idempotency keys and a cheaper climb. Choose Postmark when the sending pattern is steady and support depends on message history; choose Resend when volume is uncertain or growing.


Cost from 3,000 to 200,000 emails
| Monthly emails | Postmark | Resend |
|---|---|---|
| 3,000 | $15 (Basic; Free stops at 100) | $0 (Free) |
| 10,000 | $15 Basic, $16.50 Pro, $18 Platform | $20 (Pro) |
| 50,000 | $55 Basic, $60.50 Pro, $66 Platform | $20 (Pro) |
| 100,000 | not a slider stop | $35 (Pro, slider) |
| 125,000 | $115 Basic, $126.50 Pro, $138 Platform | not a slider stop |
| 200,000 | not a slider stop | $160 (Scale, slider) |
Postmark's 10,000-email prices differ by plan only through features and overage: Basic is $15 with $1.80 per extra 1,000, Pro is $16.50 with $1.30 and Platform is $18 with $1.20. The slider prices come from Postmark's own pricing page and cannot be recomputed from those overage rates, since Basic from 10,000 to 50,000 at $1.80 would be 15 + 40 × 1.80 = 87 rather than the $55 shown. Resend's $35 and $160 are also slider readouts; staying on the 50,000 tier and paying $0.90 per extra 1,000 for 100,000 emails would be 20 + 50 × 0.90 = 65, so move the slider rather than rely on overage. The two vendors' sliders share only the 50,000 stop, so check your own number on both before deciding. Plan summaries are on Postmark pricing and Resend pricing.
Think about the shape of your month more than the headline. Postmark's smallest paid size has a floor of $15 even if you send 4,000 emails, while Resend's Free plan would have covered that for nothing, as long as no single day exceeds 100 messages. A product that sends a burst of 500 invitations on launch day cannot use Resend Free; Pro has no daily limit. For a flat 8,000 a month on a steady schedule, Postmark Basic at $15 is the cheaper paid plan, because Resend's cheapest paid plan is $20.
Streams on one side, domains on the other
Postmark organizes sending into servers and message streams. A server holds the API token for one application, and each server starts with a default transactional stream whose ID is outbound. Streams are typed as transactional, broadcast or inbound, and Postmark says transactional and broadcast mail never share infrastructure or IP ranges (see its message streams page). A server may hold up to 10 streams, so a product can keep password resets, invoices and a newsletter on separate lanes without opening separate accounts.
Resend has no stream object. Separation happens through domains and APIs: the transactional API (/emails) and the broadcast API (/broadcasts) are billed differently, with broadcasts counting against your contacts and not against the transactional email quota, and Resend advises sending from dedicated subdomains such as updates. or account. so that each purpose builds its own reputation. Tracking is a per-domain switch, which lets you keep open and click tracking on for a newsletter subdomain and off for password resets. Free allows 3 domains, Pro 10 and Scale 1,000. Postmark Basic allows 5 custom sending domains, Pro 10 and Platform unlimited.
In practice, Postmark makes the separation hard to forget, and Resend makes it cheap to do but leaves it to you. If a new teammate could send a promotional blast through the same domain as password resets, the Postmark model protects you better.
Webhook authentication and retries
Resend signs every webhook with a secret specific to the endpoint. You can verify requests with the Resend SDK or with Svix's libraries, and the verification guide explains why: spoofed POSTs and replayed payloads are both real risks. Postmark does not sign. Its webhooks documentation says plainly that it has no HMAC signature support and tells you to protect the endpoint with HTTP Basic authentication, written into the webhook URL, and to allowlist Postmark's IP ranges. If your security review requires signature verification, that single paragraph decides the question for you.
Retry behaviour is documented on both sides. Resend retries immediately, then after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours and 10 hours, with one further 10-hour attempt, then disables an endpoint that keeps failing and emails your team; messages can be replayed manually (retries and replays). Postmark retries only on 5xx, 408, 429 and network failures, in six attempts spaced 1, 5, 10, 10, 10 and 15 minutes, and drops an event for any other 4xx answer, so a handler that returns 401 after you rotate credentials loses data. Both give you a stable identifier for deduplication: Resend repeats svix-id on retries, and Postmark sends X-PM-Webhook-Trace-Id and a unique MessageID.
Event vocabulary differs. Resend names events like email.delivered, email.bounced, email.complained, email.delivery_delayed, email.failed and email.suppressed. Postmark reports delivery, bounce, spam complaint, open, click and subscription-change events, with a RecordType field such as Delivery or Bounce. Postmark's per-message MessageID returned from a send is the key for correlating webhooks with the request that caused them.
Two send calls from the vendors' docs
Resend's idempotency documentation shows the SDK form: the second argument carries idempotencyKey. Resend checks whether the same key was used in the last 24 hours and returns the same response without sending again, which makes retrying a failed job safe. Keys may be up to 256 characters, and the suggested pattern is <event-type>/<entity-id>.
import { Resend } from 'resend';
const resend = new Resend('re_xxxxxxxxx');
await resend.emails.send(
{
from: 'Acme <onboarding@resend.dev>',
to: ['delivered@resend.dev'],
subject: 'hello world',
html: '<p>it works!</p>',
},
{
idempotencyKey: 'welcome-user/123456789',
},
); Postmark's send guide recommends sending with a stored template and an alias in TypeScript projects, returns a MessageID, and defaults to the outbound stream when you omit one. The sender must be a registered, confirmed signature or verified domain; otherwise the API answers with a 422. The send documentation we read describes no idempotency key, so retried jobs need your own deduplication.
import { ServerClient } from "postmark";
export const postmark = new ServerClient(process.env.POSTMARK_SERVER_TOKEN!);
const result = await postmark.sendEmailWithTemplate({
From: "welcome@acme.example",
To: "customer@example.com",
TemplateAlias: "welcome",
TemplateModel: { name: "Ada" },
MessageStream: "outbound",
});
console.log({ messageId: result.MessageID }); History, IPs and extras
Postmark Basic keeps 45 days of data, and Pro and Platform let you extend retention up to 365 days; a custom retention add-on starts at $5 a month. Resend keeps 30 days on every plan, including Free. Dedicated IPs are for larger senders on both: Postmark starts at $50 a month per IP, needs 300,000 emails a month or more and a Pro plan or higher, while Resend's $30-a-month add-on is open to Scale customers exceeding 3,000 emails a day. Postmark sells DMARC monitoring from $14 a month per domain, while Resend documents DMARC setup and has no monitoring product among its add-ons. Resend adds marketing broadcasts and automations (10,000 runs free, $0.0015 per run after); Postmark's pricing page lists API, SMTP, templates, inbound and a Bulk API, and routes broadcast mail through broadcast streams.
Moving between them
- Create the destination domain on a subdomain first. Resend asks for DKIM and SPF records and defaults the Return-Path to a
sendsubdomain; Postmark asks for a DKIM TXT and a Return-Path CNAME that pointspm_bouncestopm.mtasv.net, which is what lets SPF align with your From domain. - Translate streams into domains when leaving Postmark: give each stream's traffic its own subdomain, and set tracking per domain.
- Replace server tokens with a Resend API key, swap
TemplateAliasfor either inline HTML or a Resend template, and add idempotency keys to any job that retries. - Rewrite webhook handlers: drop Basic auth and IP allowlists in favor of signature verification, and change
RecordTypebranches to event types. - Import the old suppression list before the first message, and run both providers side by side on low-stakes traffic until bounce and complaint events look the same.
Going the other way, rebuild templates against Postmark's model of aliases and variables, create the streams you need, and set up Basic auth on every webhook URL you register. For authentication background see our SPF, DKIM and DMARC guide; related comparisons are Postmark vs Mailgun, Resend vs Mailgun and Resend vs SendGrid, and you can browse Postmark alternatives or Resend alternatives.
FAQ
Is Postmark cheaper than Resend for a small app?
Only in a narrow band. Resend is free up to 3,000 emails a month and $20 beyond that, while Postmark's paid plans start at $15 for 10,000. Above Resend's free allowance and up to Postmark's included 10,000, Postmark Basic is the lower paid price.
Which one verifies webhooks?
Resend does, with per-endpoint signing secrets and Svix-compatible verification. Postmark does not sign; it expects Basic auth and an IP allowlist.
Can I keep transactional and marketing mail apart on Resend?
Yes, with subdomains and the separate broadcast API, but nothing forces the split. Postmark's broadcast and transactional streams enforce it at the infrastructure level.
Which keeps message history longer?
Postmark defaults to 45 days and can reach 365 days on Pro and Platform. Resend keeps 30 days on all plans.