# Migrate from Postmark to Amazon SES

Source: https://wraps.dev/migrate/postmark

Almost nobody leaves Postmark because Postmark went wrong. They leave because the per-thousand rate stopped making sense at their volume. That makes this a different kind of migration guide: the first job is working out whether you should do it.

Below is the volume where the money argument starts to hold, the two Postmark features that have no SES replacement, and the order to work in if you go ahead.

[Price it at your volume](https://wraps.dev/tools/ses-calculator)[Postmark vs Wraps, side by side](https://wraps.dev/compare/postmark-vs-wraps)

## Stay on Postmark if this is you

We would rather you kept paying Postmark than started a migration that never finishes. Four cases where staying is the right call.

-   You send under about fifty thousand a month. The saving is real but small, and it will not repay a week of engineering plus an AWS approval inside a year.
-   Inbox placement on password resets and receipts is the thing you are paid to protect, and nobody on the team wants to own that number.
-   Postmark inbound is a product feature. Rebuilding parsed inbound on receipt rules is the biggest line item here.
-   You depend on the transactional stream refusing bulk sends. That guardrail does not exist on SES and losing it has taken production email down for other people.

The senders this move suits are past a few hundred thousand a month, own their sending code, and want delivery events landing in an account they control.

## The six gaps, stated plainly

Postmark is a narrow product that does its narrow thing very well. Everything you are trading away is in this table.

| Capability | What Postmark gives you | What you have afterwards |
| --- | --- | --- |
| Message Streams | Separate reputation and suppression per stream, bulk blocked on transactional | One account reputation. Separation is your own rule, or separate AWS accounts |
| Inbound parsing | MX record, spam score, parsed headers, stripped reply text, JSON webhook | Receipt rules to S3 or Lambda, raw MIME, Region-limited |
| Templates | Stored Handlebars, rendered by Postmark, preview and test data built in | Render in your own code, or SES templates with no preview |
| Deliverability support | Humans who answer placement questions, and a reputation they manage | AWS support, on your own reputation and your own thresholds |
| Activity history | Searchable message detail, retained on Postmark's schedule | Whatever you build or buy on top of the event stream |
| Sending approval | Account review at signup, then you send | SES production access, an AWS decision that can be refused |

## The migration, in order

Step one can end the project, which is why it is step one.

1.  1
    
    ### Price it at your real volume first
    
    This is the step people skip, and it is the only one that can tell you to stop. Postmark bills per included block with per-thousand overage. SES bills per thousand with no included block. Below roughly fifty thousand messages a month the difference is small enough that the migration does not pay for itself inside a year. Above a few hundred thousand it is not close. Put your number in the [SES calculator](https://wraps.dev/tools/ses-calculator) and decide from the answer, not from a blog post.
    
2.  2
    
    ### Write down what each Message Stream is for
    
    Streams are the part of Postmark that has no SES analogue at all. A transactional stream and a broadcast stream carry separate reputations and separate suppression, and Postmark actively refuses bulk sending on a transactional stream. That refusal is a feature: it is what stops a marketing blast from taking down password resets. On SES both go through the same account and the same reputation. Whatever kept them apart has to be rebuilt as your own rule, or accepted as a risk you now carry.
    
3.  3
    
    ### Export suppressions from every stream
    
    Suppressions are per stream, so an account-level export is not one request. Pull each one through the Suppressions API and keep the reason codes. Postmark holds hard bounces and spam complaints past the forty-five day activity window, so this export is often older and more complete than your own database, and it is the record that keeps you compliant after the switch.
    
4.  4
    
    ### Verify the domain and apply for production access
    
    Verify the sending domain in your chosen SES Region and publish the DKIM CNAMEs. File for production access the same day, because it is the one item on this list with a queue in front of it. AWS normally comes back within a day, later if it wants more detail, and it does refuse applications that do not describe the mail. The [sandbox guide](https://wraps.dev/blog/ses-sandbox-guide) and the [production access guide](https://wraps.dev/docs/guides/production-access) cover the wording that gets approved.
    
5.  5
    
    ### Recreate the templates in your codebase
    
    Postmark renders your templates on its side from stored Handlebars, and there is no bulk export button — you pull them one at a time through the API. Because SES has no comparable rendering story worth adopting, the usual answer is to render before sending. Wraps templates are React Email components in your repository, reviewed like any other code, which is a better fit for engineers and a worse fit for a marketer who was happily editing templates in a browser.
    
6.  6
    
    ### Handle inbound before you move the MX record
    
    Postmark inbound takes the MX record, parses the message, scores it for spam, strips the quoted reply, and POSTs clean JSON. SES email receiving gives you a receipt rule and the raw message in S3. Everything after that is yours to write, and only some Regions offer it at all. Do not remove the MX record pointing at `inbound.postmarkapp.com` until the replacement is handling real mail.
    
7.  7
    
    ### Cut over one stream at a time
    
    Move the least important stream first and leave password resets and receipts on Postmark until the SES numbers look boring. Compare bounce and complaint rates against the Postmark baseline for a week or two. Postmark's deliverability is genuinely good, so treat any drop as real and worth investigating rather than as noise.
    

## What you lose

The first item is the one that has cost other teams an outage.

-   The wall between transactional and broadcast. Nothing on SES stops a campaign from harming password reset delivery.
-   Parsed inbound with spam scoring and stripped replies. Receipt rules hand you raw MIME, in some Regions only.
-   Server-side template rendering with preview and test data.
-   A deliverability team that answers when placement drops.
-   Message search that already exists on day one, with no pipeline to build.
-   A signup that just works. SES production access is an application AWS can refuse.

## The published prices, side by side

### Postmark

Basic $15, Pro $16.50, Platform $18 per month — each including 10,000 emails. Overage runs $1.80, $1.30, and $1.20 per 1,000 respectively. Dedicated IP $50/mo on Pro and above, 300K/mo minimum.

The economics invert at volume — roughly $630 at 500K/mo against $50 of raw SES. Marketing tooling is deliberately thin, and the early-2026 repricing means long-standing accounts are not on these numbers.

### Amazon SES

$0.10 per 1,000 emails on à la carte. New accounts are defaulted to the Essentials plan at $0.16 per 1,000; Pro is $105/mo + $0.22 per 1,000 and Enterprise $500/mo + $0.23 per 1,000. Plans are per-account, per-Region.

Production access is an application AWS can refuse, and new accounts start sandboxed to verified addresses. No dashboard, no templates, and nothing stores your events until you build it.

Taken from each vendor's own pricing page, verified August 2026. Postmark repriced in early 2026, so a long-standing account is probably not on these numbers — check your invoice, not this table.

## Where Wraps fits

Wraps replaces the operational layer you are giving up, not the deliverability team. Being clear about that difference is the point of this section.

### What it does

-   wraps email init deploys SES with EventBridge, SQS, Lambda, DynamoDB and scoped IAM roles into your own AWS account
-   wraps email connect adopts SES identities you already verified, leaving them untouched
-   Bounces and complaints feed a suppression list checked before the next send
-   Message-level history and a dashboard, so you are not staring at CloudWatch

### What it does not

-   No stream separation. One SES account is one reputation, with or without us.
-   No inbound email parsing.
-   No deliverability desk. We ship tooling, not placement guarantees.
-   Contacts, templates, and workflow state sit in our database, not your AWS. Sending data and delivery events are what land in your account.

Platform fee only: Free ($0/mo), Pro ($29/mo), Business ($199/mo) — priced on AWS accounts, dashboard history, and governance features, not send volume. Sending is billed by AWS directly — $0.10 per 1,000 on SES à la carte, or $0.16 on the Essentials plan new AWS accounts are defaulted to. Contacts are unlimited on every tier.

## Questions people ask before they commit

### Is there a Message Streams equivalent in Amazon SES?

No. Configuration sets are the nearest structure and they separate event destinations and sending options, not reputation and not suppression. The guarantee Postmark gives you — that a broadcast cannot damage transactional delivery, because they are different streams on different reputations — does not exist on SES inside one account. Reproducing it means separate AWS accounts.

### Should I migrate if I am under 50,000 emails a month?

Probably not for the money. At that volume the gap between Postmark's published price and SES plus a platform fee is small, and the migration costs you engineering days plus a production-access application. The reasons that still hold at low volume are ownership of the sending infrastructure and keeping delivery events inside your own AWS account.

### What do I do about inbound email?

SES email receiving, in a Region that offers it, delivering to S3 or Lambda. You lose the parsed JSON, the spam score, and the stripped reply text that Postmark hands you, and you write that layer yourself. If inbound is central to your product, this is the largest single item in the migration and worth costing before you commit.

### Will deliverability get worse?

It can, and pretending otherwise would be dishonest. Postmark sells inbox placement and staffs for it. On SES you inherit AWS's shared pool and your own domain reputation, and nobody is watching your placement for you. Domain reputation carries over, so most senders see no change, but the safety net does go away.

### Can I keep my templates?

The markup, yes. The rendering, no. Postmark stores and renders Handlebars server-side; on SES you either use SES templates or render before you send. There is no converter, and pulling templates out is a per-template API call rather than an export.

## Do the arithmetic before the migration

Postmark is a good product at a price that stops working at volume. If your volume has not reached that point, the honest answer is to stay and come back later.

[Run the numbers](https://wraps.dev/tools/ses-calculator)[Other Postmark alternatives](https://wraps.dev/alternatives/postmark)
