In-depth two-product comparison
Resend vs SendGrid
Resend vs SendGrid for SaaS apps: cost at 50k, 100k and 1.5M emails, API and webhook differences, marketing plans, and migration steps either way.
Last updated: 2026-10-07
Short answer
For most SaaS developers building a new product, Resend is the better pick: its Free plan stays free at 3,000 emails a month (SendGrid's Email API free offer is a 60-day trial of 100 emails a day), the send call has an Idempotency-Key header, and at 50,000 and 100,000 emails the two cost almost exactly the same, so you give up nothing on price. SendGrid wins on three things: it is cheaper at high volume ($799 at 1.5 million emails against Resend's $825), its Pro plan includes dedicated IPs while Resend charges $30 a month for one, and its Inbound Parse and Event Webhook have longer-documented limits and two verification options. If you send more than a million emails a month or already buy from Twilio, price SendGrid first.
Resend
A free tier that does not expire, flat prices that match SendGrid at 50,000 and 100,000, and the cleanest retry story on the send call.
SendGrid
Lower published price at 1.5 million and 2.5 million emails, dedicated IPs on Pro, and a mature Inbound Parse and signed Event Webhook.
People often treat this as old against new, but the practical question is smaller: which vendor's rough edges can your team live with? Resend's are a modest batch limit and no validation. SendGrid's are a split between its Email API and Marketing Campaigns price lists, and a webhook scheme that asks you to handle raw bytes carefully. Neither is a deal breaker. Both are well-documented enough that you can prove or disprove each claim below in an afternoon.
Quick comparison
| Decision area | Resend | SendGrid | What to verify |
|---|---|---|---|
| Free offer | Free plan: 3,000 emails a month, 100 a day, 3 domains, and a free Marketing plan up to 1,000 contacts | Email API: free trial of 100 emails a day for 60 days. Marketing Campaigns: free plan for up to 2,000 contacts and 6,000 emails a month | The two free offers do different jobs: Resend lets a product send transactional mail indefinitely, SendGrid gives a limited trial for the API and a standing free plan only for campaigns. |
| Price at 50,000 emails | Pro $20 a month | Essentials $19.95 a month | A five-cent difference means price should not drive this decision; compare features and support instead. |
| Price at 100,000 emails | Pro $35 a month; Scale $90 a month | Essentials $34.95 a month; Pro $89.95 a month | SendGrid Pro includes dedicated IPs; Resend Scale lists them as a $30-a-month add-on, so compare the totals with an IP. |
| Price at 1.5 million emails | Scale $825 a month | Pro $799 a month | The $26 monthly gap is $312 a year; ask both for a written quote above a million emails, since these figures are slider readouts. |
| Send endpoint | POST /emails with a Bearer key; to up to 50 addresses; Idempotency-Key header; scheduled_at | POST /v3/mail/send with a Bearer key; up to 1,000 personalizations; dynamic template data; send_at up to 72 hours ahead | Check how far ahead you schedule: SendGrid refuses sends more than 72 hours out, and Resend documents no such limit on the page read. |
| Bulk per call | 100 emails per batch call, attachments not supported in the batch | 1,000 personalizations per Mail Send call | Divide your largest burst by 100 and by 1,000 to see how many requests each vendor needs. |
| Webhook security | Svix signatures (svix-id, svix-timestamp, svix-signature), verified with the Resend SDK or the Svix package | ECDSA signature with a timestamp header, or OAuth 2.0 client credentials; verify against the raw bytes | SendGrid ships verification helpers in seven languages; confirm yours is among them. |
| Inbound email | MX record or an id.resend.app address; a webhook announces the message and you fetch it by API | Inbound Parse: MX to mx.sendgrid.net on a dedicated hostname; the message is posted to your URL; 30 MB total | Pick a receiving hostname that your transactional domain does not use; SendGrid warns about a bounce loop if they overlap. |
| Dedicated IP | $30 a month, for Scale customers sending more than 3,000 emails a day | Included on the Email API Pro plan and above; dedicated IP access listed on Marketing Campaigns Advanced | Ask each vendor about warm-up before you assume the IP will carry full volume on day one. |
| Contact-based marketing | Free at 1,000 contacts; $40 at 5,000; $80 at 10,000; $180 at 25,000; $250 at 50,000; $450 at 100,000 | Free up to 2,000 contacts and 6,000 emails a month; Basic from $15; Advanced from $60; custom above | SendGrid prices Marketing Campaigns on its own selector; move it to your contact count rather than relying on the starting price. |
Resend steps its price at published slider stops and SendGrid reads its plan selector at published volumes. The two share 50,000, 100,000 and 1.5 million, so those are the rows to trust. SendGrid also reads $249 at 300,000 and $499 at 700,000, volumes where Resend publishes no stop; the tables do not guess a Resend figure between its $160 at 200,000 and $350 at 500,000.
Feature comparison
| Feature | Resend | SendGrid |
|---|---|---|
| Send request | A single JSON POST to /emails: from, to and subject required, up to 50 recipients, tags as name and value pairs, attachments up to 40 MB per email after Base64. | POST https://api.sendgrid.com/v3/mail/send needs personalizations and from; personalizations take up to 1,000 items, each with its own cc, bcc and data. |
| Duplicate protection | Idempotency-Key header: unique per request, 24-hour lifetime, up to 256 characters. | The Mail Send reference read for this page lists no idempotency header; successful requests return 202 Accepted. |
| Templates | template with an id or alias and variables; a template cannot be combined with html, text or react; the react parameter works in the Node.js SDK only. | Dynamic templates have IDs starting d-, several versions per template, a visual or code editor and Handlebars with conditions and loops, filled from dynamic_template_data. |
| Scheduling | scheduled_at in natural language or ISO 8601. | send_at as a Unix timestamp, per message or per personalization; never more than 72 hours ahead. |
| SDKs | Official: Node.js, PHP, Laravel, Python, Ruby, Go, Java, Rust, .NET. | Official: C#, Go, Java, Node.js, PHP, Python, Ruby, each with an SMTP API header helper. |
| SMTP | smtp.resend.com, username resend, API key as the password, ports 25, 465, 587, 2465 and 2587. | smtp.sendgrid.net on port 587, username apikey, an API key with Mail Send permission as the password, and an X-SMTPAPI JSON header for per-message settings. |
| Event types | email.sent, delivered, delivery_delayed, bounced, complained, opened, clicked, failed, scheduled, suppressed and received, plus contact, domain, topic and suppression events. | processed, dropped, delivered, deferred, bounce, open, click, spam report, unsubscribe, group_unsubscribe and group_resubscribe. |
| Retries and replay | Eight attempts: immediately, 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 10 hours; any message can be replayed from the dashboard. | Retried at increasing intervals for up to 24 hours per event, on a rolling basis; redirects are not followed; use sg_event_id to deduplicate. |
| Inbound | Webhook on arrival; HTML, text and headers fetched through the API; attachments by temporary URL. | Inbound Parse posts multipart/form-data; Send Raw returns the full MIME; spam scoring is applied to messages up to 2.5 MB; 5xx responses are retried. |
| Suppression model | One team-wide list with origins bounce, complaint and manual, applied across domains to transactional and broadcast mail. | Separate lists for blocks, bounces, invalid emails, spam reports and global unsubscribes; a block is temporary and does not suppress the address. |
| Campaign product | Marketing tab: broadcasts to segments, automations (the pricing page lists $0.0015 per run), topics for subscription categories. | Marketing Campaigns is a separate product with its own plans: Free, Basic, Advanced and Custom. |
| Data processing terms | Resend links a DPA at resend.com/legal/dpa; read it before relying on it for EU data. | Twilio publishes a Data Protection Addendum that forms part of the customer agreement; the pricing pages do not name a hosting region. |
Pricing and operating cost
Resend
Free plan, not a trial: 3,000 emails a month, 100 a day and 3 domains. The Marketing side is free up to 1,000 contacts with unlimited broadcasts, 10,000 automation runs and 3 segments.
A dedicated IP is a $30 monthly add-on, available only to Scale customers sending more than 3,000 emails a day. Single sign-on is a $150-a-month add-on, and more than the included domains costs $20 a month per extra 100. Resend's pricing page lists automations at $0.0015 per run, which matters once a Marketing workflow runs at volume. Both sent and received emails count toward your quota.
SendGrid
Email API: a free trial of 100 emails a day for 60 days, with no credit card. Marketing Campaigns has a free plan for up to 2,000 contacts and 6,000 emails a month.
The Email API's free offer ends after 60 days, and the Marketing Campaigns free plan is a separate product with its own limits. Prices are 'starting at' figures with taxes and overages possible, so read the selector at your real volume. Messages can be dropped or blocked by suppression lists that you may not notice without watching Event Webhook data. Email API and Marketing Campaigns are billed as separate plans, so a company using both pays two bills.
| Tier or usage case | Resend | SendGrid |
|---|---|---|
| Free | $0 (3,000 emails a month) Daily and monthly quota errors both return 429; the daily one resets at midnight UTC. | $0 for 60 days (100 a day) After the trial the Email API needs a paid plan; Marketing Campaigns free plan is separate. |
| 50,000 emails a month | Pro $20 Yearly $240. | Essentials $19.95 Yearly $239.40. |
| 100,000 emails a month | Pro $35; Scale $90 Pro yearly $420; Scale yearly $1,080. | Essentials $34.95; Pro $89.95 Essentials yearly $419.40; Pro yearly $1,079.40, with dedicated IPs included. |
| 1,500,000 emails a month | Scale $825 Yearly $9,900. At 1,000,000 the slider reads $650 and at 2,500,000 it reads $1,150. | Pro $799 Yearly $9,588. The selector also reads $249 at 300,000, $499 at 700,000 and $1,099 at 2,500,000. |
What each vendor charges at 50,000, 100,000 and 1.5 million emails
At 50,000 emails a month Resend's pricing page reads Pro at $20, and the SendGrid Email API pricing page reads Essentials at $19.95. Over a year that is $240 against $239.40, so the decision at this size cannot rest on price.
At 100,000 emails Resend Pro reads $35 and SendGrid Essentials reads $34.95. The higher tiers match nearly as closely: Resend Scale is $90 and SendGrid Pro is $89.95 (yearly $1,080 against $1,079.40). The difference is what the higher plan carries. SendGrid Pro lists dedicated IPs. Resend Scale lists 1,000 domains and a dedicated Slack channel, with a dedicated IP as a $30-a-month add-on for customers sending more than 3,000 emails a day. A team that wants its own IP therefore pays $89.95 on SendGrid and $120 on Resend at 100,000 emails.
At 1.5 million emails SendGrid Pro is $799 and Resend Scale is $825: SendGrid is $26 a month cheaper, $312 a year. Further up, SendGrid Pro reads $1,099 at 2,500,000 and Resend Scale reads $1,150, a $51 monthly gap and $612 a year. In the middle, SendGrid also publishes $249 at 300,000 and $499 at 700,000, while Resend's published stops are $160 at 200,000, $350 at 500,000 and $650 at 1,000,000, so those volumes cannot be compared like for like. Only at 1.5 million and above does SendGrid have a consistent, small price edge.
The send call: idempotency, scheduling and bulk limits
Resend's send email reference lets you attach an Idempotency-Key to each request, so a client that times out and retries will not send twice; keys last 24 hours. It also offers scheduled_at in natural language, template sends by id or alias with variables, and tags. The batch endpoint sends up to 100 emails per call and does not accept attachments. The default limit is 10 requests per second per team.
SendGrid's Mail Send reference centres on personalizations: one request can hold up to 1,000 of them, each with its own recipients and template data, which is why SendGrid needs far fewer requests for a large fan-out. A send is accepted with a 202. send_at takes a Unix timestamp but never more than 72 hours ahead, so a reminder that must go out a week from now needs your own scheduler. Dynamic templates use IDs starting with d-, and their Handlebars supports conditions and loops, as the dynamic templates guide describes.
For a monthly invoice run to 40,000 customers, SendGrid can do the job in 40 requests of 1,000 personalizations, while Resend needs 400 batch calls of 100, 40 seconds of calls at the default limit. Neither is hard, but the loop looks different, and Resend's loop needs a queue.
Webhooks: Svix on one side, ECDSA or OAuth on the other
Resend's webhooks use Svix. The verification guide says to read the svix-id, svix-timestamp and svix-signature headers and pass them, with the raw body and your endpoint's signing secret, to the Resend SDK verify method or to the Svix package. A failure throws. The retries page lists eight attempts over more than 27 hours, lets you replay both failed and successful messages from the dashboard, and disables an endpoint that keeps failing, with an email to your team.
SendGrid offers two methods that can run together. The security features guide describes an ECDSA signature in the X-Twilio-Email-Event-Webhook-Signature header with a timestamp in X-Twilio-Email-Event-Webhook-Timestamp; you hash the timestamp plus the raw payload bytes with SHA-256 and check it against the public key, using the helper in one of seven SendGrid libraries. The other is OAuth 2.0 with client credentials: SendGrid fetches a token and sends it in an Authorization header, and you verify it. The guide warns that converting the payload to a JSON string can alter the characters that were signed.
SendGrid retries a failed event for up to 24 hours on a rolling basis, does not follow redirects, and gives each event an sg_event_id for deduplication. Both vendors want raw bytes, so the common failure is a framework that parses the body first. With Resend you get a library call and a replay button; with SendGrid you get two options, which suits a security team that already runs OAuth for machine-to-machine traffic.
Inbound mail and suppression handling
Resend receiving works at a Resend-managed id.resend.app address or at your own domain after adding an MX record, per the receiving guide. It parses the message, posts to your endpoint, and lets you fetch HTML, text and headers by API, with attachments as temporary download URLs.
SendGrid's Inbound Parse points an MX record at mx.sendgrid.net (priority 10) on a hostname used for nothing else, associates it with your URL, and posts multipart/form-data. The total message size limit is 30 MB. A spam score and report are added for messages up to 2.5 MB, and Send Raw returns the full MIME. If the receiving domain is also your authenticated sending domain, Automatic Security on the authenticated domain must be turned off, otherwise messages loop between the CNAME and MX servers.
For suppression, Resend keeps one team-wide suppression list with three origins (bounce, complaint, manual); the API adds or removes up to 100 addresses per call. SendGrid keeps separate lists, as its suppressions documentation shows: blocks (temporary, not suppressed), bounces, invalid emails, spam reports and global unsubscribes. The Mail Send API can also bypass list management for a request. The separate lists give finer control and more to export during a migration.
Marketing sends: Resend Marketing tab against Marketing Campaigns
Resend's Marketing tab prices by contacts: free at 1,000 contacts with unlimited broadcasts, 10,000 automation runs and 3 segments, then $40 at 5,000, $80 at 10,000, $180 at 25,000, $250 at 50,000 and $450 at 100,000. Broadcasts go to a segment and topics let recipients choose which categories they receive.
SendGrid's Marketing Campaigns has a free plan for up to 2,000 contacts and 6,000 emails a month, Basic from $15 for up to 100,000 contacts and 300,000 emails, and Advanced from $60 for up to 200,000 contacts and 1,000,000 emails, with dedicated IP access. Because the starting prices are minimums, move the selector to your contact count before comparing against Resend's readouts. For a list of 1,800 contacts the SendGrid free plan is enough, while Resend's free Marketing plan stops at 1,000.
Moving from SendGrid to Resend
If you used Marketing Campaigns, export contacts as CSV, create segments in Resend, and map SendGrid's unsubscribe groups to topics. The group_unsubscribe events already stored in your database show which groups you used.
- Add your domain to Resend and publish the records. Resend suggests sending from subdomains, so give transactional and newsletter mail separate ones. Keep SendGrid live while DNS propagates.
- Swap credentials: an API key in the Bearer header, or smtp.resend.com with the username resend and the key as the password in place of SendGrid's apikey username.
- Translate each Mail Send payload. Personalizations become one email per recipient (or up to 100 per batch call), dynamic_template_data becomes template variables, categories and custom args become tags or headers, and send_at becomes scheduled_at. Remember reserved variable names: FIRST_NAME, LAST_NAME, EMAIL and UNSUBSCRIBE_URL.
- Rebuild templates. SendGrid dynamic templates use Handlebars conditions and loops; the Resend template pages read describe variable substitution, so move conditional blocks into your code or render HTML with React or another renderer before sending.
- Replace the ECDSA or OAuth check with Svix verification on the raw body. Map delivered to email.delivered, deferred to email.delivery_delayed, bounce to email.bounced and spam report to email.complained, then check how your handling of dropped events maps to email.suppressed.
- Export SendGrid's bounces (up to 500 per API query, with offsets) and global unsubscribes, and add them to Resend's suppression list. Convert Inbound Parse to Resend receiving by moving the MX record and rewriting the handler to fetch the body by API.
- Add Idempotency-Key headers to retried sends, and queue bulk jobs to respect 10 requests per second. Send password resets first, watch webhook events for a week, then move the rest.
Moving from Resend to SendGrid
- Create an API key with Mail Send permission, verify the sender identity and authenticated domain, and keep Resend's records in place until the cutover.
- For SMTP use smtp.sendgrid.net on port 587 with the username apikey. Per-message settings travel in the X-SMTPAPI header.
- Rewrite the send call for POST /v3/mail/send. Put recipients and per-recipient data in personalizations (up to 1,000 per request), and move template sends to a dynamic template with a d- ID and dynamic_template_data. Render React Email components to HTML yourself, because there is no react parameter.
- Plan around send_at: SendGrid will not schedule more than 72 hours ahead, so any Resend scheduled_at further out needs your own scheduler. The Mail Send page read lists no idempotency header, so keep a send ledger before retrying.
- Replace Svix verification with the ECDSA check on the raw bytes, or use OAuth 2.0 client credentials. Map email.bounced to bounce, email.delivery_delayed to deferred, email.complained to spam report, and deduplicate on sg_event_id.
- Move suppressions with the Global Suppressions API, and receiving with Inbound Parse: an MX record to mx.sendgrid.net at priority 10 on a dedicated hostname, which the SendGrid docs say not to change afterwards.
- If you used Resend's Marketing tab, load contacts into Marketing Campaigns and check the plan selector at your contact count. Choose the Pro Email API plan if you want dedicated IPs included.
Pros and cons
Resend
Pros
- A permanent free plan of 3,000 emails a month, with a free Marketing plan up to 1,000 contacts.
- Price within five cents of SendGrid at 50,000 and 100,000 emails.
- Idempotency-Key, scheduled_at and template variables on the send call.
- Svix verification in one library call, plus dashboard replay of any webhook message.
- Nine official SDKs, including Rust and .NET.
Cons
- $26 a month more than SendGrid at 1.5 million emails, $51 more at 2.5 million.
- Batch calls carry only 100 emails and no attachments.
- Dedicated IPs are a $30 add-on and only for Scale customers over 3,000 emails a day.
- No address validation endpoint listed.
SendGrid
Pros
- Lower published price at 1.5 and 2.5 million emails.
- 1,000 personalizations per request and 30 MB Inbound Parse messages.
- Dedicated IPs included on Email API Pro.
- Event Webhook can be secured by ECDSA, OAuth 2.0 or both.
- A free Marketing Campaigns plan for up to 2,000 contacts.
Cons
- The Email API's free offer is a 60-day trial of 100 emails a day.
- No idempotency header in the Mail Send reference read.
- send_at cannot be more than 72 hours ahead.
- Email API and Marketing Campaigns are separate plans and bills.
Who should choose what?
New B2B product on a TypeScript stack, 20,000 to 100,000 emails a month
Transactional mail from a Next.js backend, no existing Twilio account, a team that wants retries to be safe.
Recommendation: Resend. At 50,000 and 100,000 emails the prices are within five cents, so pick on ergonomics: Resend gives an Idempotency-Key header, one-call Svix verification and a free plan that does not expire, where SendGrid's API offer is a 60-day trial.
Notification platform at 1.5 million emails a month
Steady high volume where list prices start to matter and you have budget for a procurement conversation.
Recommendation: SendGrid. SendGrid Pro reads $799 against Resend Scale at $825, a $312 yearly difference that grows to $612 at 2.5 million. Get both quotes in writing since these are selector readouts.
A dedicated IP at 100,000 emails a month
You want your own IP to isolate reputation from other senders.
Recommendation: SendGrid. SendGrid Pro at $89.95 includes dedicated IPs. Resend Scale at $90 plus the $30-a-month IP add-on is $120, and the add-on is open only to customers sending more than 3,000 emails a day.
Newsletter list of 1,800 contacts next to product email
A small audience for monthly updates, with transactional sends from the same vendor.
Recommendation: SendGrid. SendGrid's Marketing Campaigns free plan covers up to 2,000 contacts and 6,000 emails a month. Resend's free Marketing plan ends at 1,000 contacts, so this list would need a paid slider stop.
Event-driven product with fragile downstream consumers
Webhook handlers write to your billing and CRM systems, and an outage can leave events unprocessed.
Recommendation: Resend. Resend lets you replay any failed or successful webhook message from the dashboard and disables a broken endpoint with an email to your team. SendGrid retries for 24 hours but offers no replay in the pages read.
Support inbox that accepts large attachments
Customers email screenshots and logs to a help address that feeds your ticket system.
Recommendation: SendGrid. SendGrid Inbound Parse documents a 30 MB total message size, a spam score on smaller messages and a Send Raw option. Resend's receiving page reads no numeric limit, so you would have to confirm one before relying on it.
The scenarios split by volume, by whether you need a dedicated IP, and by whether your list is small enough for SendGrid's free Marketing plan. When none of those apply, the developer ergonomics of the send call usually decide it.
Final verdict
Choose Resend if
- you are building a new product and want a free plan that does not expire
- your volume sits between 50,000 and 1 million emails and price is a tie
- retry safety on the send call and replayable webhooks matter to your team
- you want broadcasts and transactional mail from one account priced by contacts
Choose SendGrid if
- you send 1.5 million emails a month or more and the published edge matters
- you need dedicated IPs included with the plan
- you want inbound mail with a documented 30 MB limit and a raw MIME option
- you want OAuth 2.0 or ECDSA on your webhooks, or already buy from Twilio
FAQ
Is Resend cheaper than SendGrid?
Not by much until volume is large. At 50,000 emails Resend Pro is $20 and SendGrid Essentials is $19.95; at 100,000 it is $35 against $34.95. At 1.5 million emails SendGrid Pro is $799 and Resend Scale is $825. Resend's advantage is its permanent free plan.
Does SendGrid have a free plan?
The Email API offers a free trial of 100 emails a day for 60 days with no credit card. Marketing Campaigns has a separate free plan for up to 2,000 contacts and 6,000 emails a month. Resend's Free plan is 3,000 emails a month with a 100-a-day cap and no end date.
How are webhooks secured on each?
Resend signs with Svix, and you verify svix-id, svix-timestamp and svix-signature with the raw body. SendGrid offers an ECDSA signature (with a timestamp header) and OAuth 2.0 client credentials. In both cases you must use the raw request body, not a re-serialised copy.
Can both handle inbound email?
Yes. Resend receives at an id.resend.app address or your own domain with an MX record and sends a webhook; you fetch the body by API. SendGrid Inbound Parse uses an MX record to mx.sendgrid.net and posts the parsed message, with a 30 MB total size limit.
What is hardest about switching?
Templates and webhooks. SendGrid dynamic templates have Handlebars conditions and loops, which may need to move into code for Resend, and event names change. Resend's batch call takes 100 messages without attachments against SendGrid's 1,000 personalizations, so bulk jobs change shape.