---
title: Migrating from SendGrid to AWS SES: Complete Guide
description: Practical migration guide from SendGrid to AWS SES. Email deliverability setup, features, and infrastructure integration.
url: https://www.factualminds.com/compare/sendgrid-to-aws-ses/
publishDate: 2025-05-01
updateDate: 2026-06-16
---

# Migrating from SendGrid to AWS SES: Complete Guide

> Step-by-step guide for engineers migrating from SendGrid to AWS SES — including the pricing math, API mapping, unsubscribe handling, and reputation warming strategy you need before you flip the switch.

<div class="quick-answer">

**Quick Answer:** AWS SES is usually the better fit when you need lower unit email cost, AWS-native eventing, and tighter deliverability controls at scale.

</div>

## Freshness Check (June 2026)

In this cycle, SES updates include tenant-level suppression lists, inbox placement metrics, and email validation capabilities that materially improve migration operating models.

This page was refreshed against official AWS announcements and service documentation published in the last 12 months. Confirm region support, quotas, and pricing before final architecture sign-off.

- [AWS What's New](https://aws.amazon.com/about-aws/whats-new/)
- [SES announcement updates](https://aws.amazon.com/about-aws/whats-new/2026/06/amazon-ses-tenant-level-suppression-lists/)

SendGrid is the default choice for teams that need email infrastructure fast. AWS SES is what teams move to when the SendGrid bill becomes hard to justify — especially once they are already running workloads on AWS. This guide covers everything an engineer or DevOps lead needs to execute the migration successfully.

## Related Comparisons

Explore other technical comparisons:

- [Mailgun to AWS SES](/compare/mailgun-to-aws-ses/)
- [Postmark to AWS SES](/compare/postmark-to-aws-ses/)

## Why Teams Migrate from SendGrid to SES

The primary driver is cost. At low volumes, the difference is modest. At scale, it is dramatic.

| Volume           | SendGrid Essentials | AWS SES       | Monthly Savings |
| ---------------- | ------------------- | ------------- | --------------- |
| 50,000 emails    | $19.95/month        | $5.00/month   | $14.95          |
| 100,000 emails   | $89.95/month        | $10.00/month  | $79.95          |
| 500,000 emails   | $249/month (Pro)    | $50.00/month  | $199.00         |
| 1,000,000 emails | $449/month (Pro)    | $100.00/month | $349.00         |

SES charges $0.10 per 1,000 emails. There is no monthly minimum, no plan tier, and no overage. If you are already on AWS, outbound email sent from EC2 or Lambda is free for the first 62,000 emails per month.

The secondary drivers are consolidation (fewer vendors, unified AWS billing) and tighter IAM-based access control.

## API Migration: SendGrid v3 → AWS SES

SendGrid's v3 API and AWS SES use different request models, but the conceptual mapping is direct.

| SendGrid v3                          | AWS SES Equivalent                                    | Notes                                        |
| ------------------------------------ | ----------------------------------------------------- | -------------------------------------------- |
| `POST /v3/mail/send`                 | `SendEmail` API                                       | Core send operation                          |
| `personalizations[]`                 | `Destinations[]` (bulk) or individual calls           | SES `SendBulkEmail` for templated bulk sends |
| `from`, `to`, `subject`, `content`   | `Message.Body`, `Destination`, `Source`               | Same fields, different structure             |
| API key header auth                  | IAM credentials or SES SMTP credentials               | IAM is preferred for AWS-native apps         |
| SMTP relay (host: smtp.sendgrid.net) | SMTP relay (host: email-smtp.us-east-1.amazonaws.com) | Port 587 (STARTTLS) or 465 (SSL)             |

If your application uses SMTP rather than the REST API, the migration is a three-line config change: update the host, port, username, and password. SES SMTP credentials are generated in the SES console under SMTP Settings.

## Dynamic Templates vs SES Templates

This is the most significant feature gap. SendGrid Dynamic Templates offer a visual editor, Handlebars syntax with conditionals and loops, and per-template version history.

SES email templates support `{{variable}}` substitution and limited conditional blocks. There is no visual editor.

**Recommended migration approach:** move template rendering to your application code.

Libraries that work well:

- **MJML** — responsive email markup that compiles to HTML
- **React Email** — component-based email templates with JSX
- **Handlebars / Nunjucks** — logic-capable server-side templating

Render the HTML body in your application, then call `SES.sendEmail()` with the rendered content. This decouples template logic from your email provider, making future migrations trivial.

## Unsubscribe and Suppression List Migration

SendGrid manages suppression lists (unsubscribes, bounces, spam reports, invalid emails) automatically. SES requires you to build or integrate this logic.

**Steps:**

1. Export your SendGrid suppression lists (Global Unsubscribes, Bounces, Spam Reports, Invalid Emails) via the SendGrid UI or API
2. Upload hard bounces and spam reports to the SES account-level suppression list via the SES console or `PutSuppressedDestination` API
3. Configure an SNS topic as the event destination in a SES Configuration Set
4. Write a Lambda handler that receives bounce/complaint events and writes addresses to your suppression store (DynamoDB or RDS) and optionally to the SES account-level suppression list

SES's account-level suppression list handles hard bounces and complaints automatically across all sends once populated, but it does not provide a UI for end-user unsubscribe management. You need to implement that in your application if you send marketing or newsletter email.

## IP Warming Strategy

Both SendGrid and SES require IP warming when moving to a dedicated IP. If you are migrating to SES shared IP pools, warming is less critical but still advisable.

**SES dedicated IPs cost $24.95 per IP per month.** For most transactional senders under 500,000 emails/month, the shared IP pool is sufficient.

Warming schedule for a dedicated IP (approximate):

| Day Range  | Daily Volume Cap    | Rationale                                                       |
| ---------- | ------------------- | --------------------------------------------------------------- |
| Days 1–3   | 200 emails/day      | Mailbox providers observe sender behavior; start conservatively |
| Days 4–6   | 500 emails/day      | Gradual increase; mailbox providers building reputation profile |
| Days 7–9   | 1,000 emails/day    | Consistent sending establishes trust                            |
| Days 10–12 | 2,000 emails/day    | Continue gradual ramp                                           |
| Days 13–15 | 5,000 emails/day    | Halfway through warming period                                  |
| Days 16–18 | 10,000 emails/day   | Reputation is building; can accelerate                          |
| Days 19–21 | 20,000 emails/day   | Final ramping phase                                             |
| Days 22–24 | 50,000 emails/day   | Approaching full volume                                         |
| Days 25–27 | 100,000 emails/day  | Nearly at target                                                |
| Days 28–30 | Full sending volume | Reputation established; send at full capacity                   |

**Critical metrics during warming:** Monitor bounce rate (keep below 2%) and complaint rate (keep below 0.1%). One complaint per 1,000 emails is typical; higher signals list quality issues.

## Email Authentication: SPF, DKIM, DMARC, and BIMI

SendGrid configures most authentication for you behind the scenes. On SES, you own it — which is good for control, but means you cannot skip the setup. Mailbox providers (Gmail, Yahoo, Microsoft) now treat unauthenticated mail as effectively undeliverable for any sender doing meaningful volume.

**SPF.** Add `include:amazonses.com` to your sending domain's SPF record. If you already publish SPF for other senders, append rather than replace — exceeding the 10-DNS-lookup limit silently breaks SPF and is one of the most common deliverability regressions during a migration.

**DKIM.** Enable Easy DKIM in the SES console for each verified identity. SES generates three CNAME records; publish all three. Easy DKIM rotates keys automatically, which is the right default. BYODKIM is only worth the operational overhead when you need to align DKIM signing across multiple ESPs during a phased cutover.

**DMARC.** Publish `_dmarc.yourdomain.com` with at minimum `v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com` on day one to start collecting aggregate reports. Move to `p=quarantine` after two to four weeks of clean reports, and to `p=reject` once you are confident every legitimate sender is aligned. Gmail and Yahoo's 2024 bulk-sender requirements (DMARC mandatory above 5,000 messages/day per mailbox provider) are now the deliverability floor, not a ceiling — by 2026, sustained `p=none` on a bulk sender is increasingly read as a misconfiguration signal by reputation systems. Plan to land on `p=quarantine` or `p=reject` rather than treating the minimum as a destination.

**BIMI.** Once you reach `p=quarantine` or stricter and have a Verified Mark Certificate (VMC), publish a BIMI record so your brand logo renders in Gmail, Apple Mail, and Yahoo inboxes. BIMI does not directly improve deliverability, but the trust signal lifts open rates measurably for transactional and lifecycle email.

A common migration mistake is leaving the SendGrid CNAMEs in place after cutover. Audit DNS and remove orphaned authentication records — stale `s1._domainkey.u1234.wl.sendgrid.net` references do not cause failures, but they pollute DMARC alignment reports and make troubleshooting harder.

## Domain Reputation, List Hygiene, and Engagement-Based Sending

SES does not give you a SendGrid-style reputation dashboard out of the box. You build the equivalent from CloudWatch metrics, SNS event streams, and Google Postmaster Tools / Microsoft SNDS. The migration is the right time to tighten list hygiene, because reputation built on a clean list is durable; reputation built on a stale list is borrowed time.

**List hygiene before cutover.**

- Suppress any address that has not opened or clicked in the last 6–12 months for marketing streams. Re-engagement campaigns should run on the legacy provider, not the new IP.
- Run a syntax + MX validation pass on your active list. Free or paid validators catch role accounts, disposable domains, and typo'd `gmial.com` entries that drive the bounce rate above the SES 2% threshold.
- Import SendGrid's hard-bounce and complaint history into the SES account-level suppression list before sending the first production message.

**Segmentation that mailbox providers reward.** Segment by engagement recency (0–30 day, 30–90 day, 90+ day) and send to the most engaged segment first when warming. Gmail and Microsoft weigh recent positive engagement (opens, replies, "move to inbox") far more heavily than total volume, so a smaller, hotter list lifts inbox placement for the entire domain.

**Sending cadence and throttling.** SES enforces a per-second send rate and a 24-hour quota that grow with reputation. Respect both:

- Use SES Configuration Set sending pools to isolate transactional from marketing traffic so a marketing reputation hit does not affect password resets.
- Smooth marketing sends across hours rather than firing a million messages at minute zero — bursty patterns trigger greylisting at smaller mailbox providers and look like list-bombing to spam classifiers.
- For high-volume blasts, use SES `SendBulkEmail` with batched destinations and respect the per-account TPS by throttling at the SDK or queue layer.

**Engagement-based filtering.** The modern deliverability pattern is to stop sending to disengaged subscribers entirely. Maintain a "send eligibility" flag in your subscriber store, updated nightly from SES open/click events, and exclude anyone who has not engaged in your defined window. This is the single highest-leverage change most teams make post-migration — it typically moves inbox placement from the mid-80s to the mid-90s within 30 days.

## Tracking SES Events at Scale: Kinesis Firehose → S3 → Node.js API

The SNS-to-Lambda pattern from the suppression section works well for tens of thousands of events per day. Past that volume, or if you need historical analytics, the production-grade pipeline is **SES → Kinesis Data Firehose → S3 → Node.js API**.

**How it works.**

1. **SES Configuration Set** — define one Configuration Set per sending stream (transactional, marketing, lifecycle) and attach a Kinesis Firehose event destination. Subscribe to all event types: `send`, `delivery`, `bounce`, `complaint`, `open`, `click`, `reject`, `renderingFailure`, `deliveryDelay`, and `subscription`.
2. **Kinesis Data Firehose** — buffers events (typically 60 seconds or 5 MB) and writes newline-delimited JSON to S3 partitioned by `year/month/day/hour`. Enable dynamic partitioning to also split by Configuration Set or sending IP for downstream filtering.
3. **S3 with lifecycle policy** — store raw events in Standard for 30 days (hot analytics window), transition to Standard-IA at 30 days, and to Glacier Flexible Retrieval at 180 days. Raw event archives are typically the cheapest part of the stack and the most useful during deliverability investigations.
4. **Node.js API** — consume events either by tailing new S3 objects via S3 Event Notifications → SQS → Node.js worker (Express or Fastify behind ALB, or a Lambda function for spiky traffic), or by querying historical data through Amazon Athena. The API exposes per-recipient timelines, per-campaign engagement, and per-domain placement metrics to your dashboards.

**Why this beats SNS → Lambda at scale.**

- **Decoupling.** Lambda concurrency limits and DLQ replay are a real operational tax above ~50 events per second. Firehose absorbs spikes and replays automatically.
- **Replayable history.** S3 is the source of truth. You can rebuild a recipient timeline, re-run a deliverability analysis, or backfill a new dashboard without re-fetching from a vendor API.
- **Cheap analytics.** Athena over partitioned S3 lets you answer "what was my Gmail open rate by sending IP last week?" in seconds and dollars, not hours and engineering tickets.
- **Audit trail.** Compliance and abuse investigations require raw event history. Firehose-to-S3 gives you that immutably; SNS-only does not.

**Tracking nuance to plan for.** SES open events fire on pixel load and click events fire on the SES tracking redirector. Both are noisy: corporate proxies, spam filters, and Apple Mail Privacy Protection all pre-fetch images and follow links, generating engagement signals that have nothing to do with a human reading the message. Without filtering, your "open rate" double-counts machine activity and your engagement-based suppression logic suppresses people who actually engaged.

This is where a tool like [InboxEagle's Bot Finder](https://www.inboxeagle.com/) earns its place in the pipeline — it analyzes SES open and click streams, distinguishes human engagement from bot and proxy activity (Apple MPP, Microsoft Defender, Gmail image proxy, link-scanning gateways), and lets your Node.js API serve cleaned engagement data to downstream systems. Plug it in between the S3 raw layer and the engagement-based filtering layer described above, and your reputation signals match real subscriber behavior rather than scanner noise.

## Why Choose FactualMinds for Your Email Migration

FactualMinds is an **AWS Select Tier Consulting Partner** specializing in email infrastructure migration. We have executed SendGrid, Mailgun, Postmark, and SparkPost to AWS SES migrations and know exactly where teams get stuck.

- **Email migration experts** — we handle domain verification, DKIM, bounce architecture, IP warming
- **Assessment-first approach** — we map your current state before writing a line of infrastructure code
- **Zero-downtime cutover planning included** — no failed deliveries during migration
- **AWS Select Tier Partner** — [verified on AWS Partner Network](https://partners.amazonaws.com/partners/001aq000008su2EAAQ/Factual%20Minds)

---

## FAQ

### Is AWS SES better than SendGrid?
It depends on your requirements. AWS SES is significantly cheaper at volume — $0.10 per 1,000 emails versus SendGrid Essentials at roughly $0.40 per 1,000 at the 50K tier. SES wins on cost and AWS-native integration. SendGrid wins on out-of-the-box deliverability tooling, a richer template editor, and per-message engagement analytics. If you send more than 50,000 emails per month and are already on AWS, SES almost always makes economic sense. If deliverability debugging and template management are business-critical and your team lacks AWS expertise, SendGrid's higher price may be justified.

### How long does it take to migrate from SendGrid to SES?
A straightforward migration — single domain, transactional email only, SMTP relay swap — can be completed in one to two days. A full migration including custom dedicated IPs, template conversion, suppression list import, SNS-based bounce handling, and IP warming takes two to four weeks. The warm-up period for a dedicated IP is typically 30 days of gradually increasing volume before you can send at full capacity. Plan for parallel sending during the warm-up to avoid deliverability regression.

### Does AWS SES have email templates?
Yes, but with significant limitations compared to SendGrid. SES templates support simple variable substitution using {{variable}} syntax and basic conditional blocks, but lack the drag-and-drop editor, design components, and rich conditional logic of SendGrid Dynamic Templates. Most teams migrating from SendGrid move template rendering to application code — using libraries like MJML, React Email, or Handlebars — and send the pre-rendered HTML body to SES. This gives you more control and removes the dependency on the ESP template system entirely.

### How do I handle bounces in AWS SES?
SES delivers bounce and complaint notifications through Amazon SNS. You configure a Configuration Set with an SNS event destination, then subscribe a Lambda function or HTTP endpoint to the SNS topic. Your handler receives JSON payloads for bounces (hard and soft), complaints, and deliveries. You are responsible for maintaining your own suppression logic — adding hard-bounce addresses and complaint addresses to a do-not-send list and never retrying them. SES also has an account-level suppression list that automatically blocks future sends to addresses that have hard-bounced or complained across any SES customer.

### Is AWS SES cheaper than SendGrid?
Yes, substantially. At 50,000 emails per month, SendGrid Essentials costs $19.95 versus $5.00 on SES. At 100,000 emails per month, SendGrid Essentials costs $89.95 versus $10.00 on SES. At 1,000,000 emails per month, SendGrid Pro costs $449 versus $100 on SES. The savings compound quickly. The only cost scenarios where they converge are very low volumes (under 10,000 emails per month, where SendGrid Free tier applies) or if you need dedicated IPs on SES ($24.95 per IP per month) and SendGrid shared IPs serve your deliverability needs adequately.

---

*Source: https://www.factualminds.com/compare/sendgrid-to-aws-ses/*
