All posts
Amazon SES production setup: review the whole sending path
SendHog engineering8 min read

Editorial date: . First published October 19, 2026.

Amazon SES production setup: review the whole sending path

Leaving the SES sandbox is one checkpoint, not a production-readiness test. Review regional access, identity, credentials, feedback, recipient policy, and ambiguous sends before application traffic depends on them.

A production-readiness ladder separates regional access, authenticated identity, application permissions, feedback, and controlled rollout.

Start with the region, not the credentials

SES production access belongs to an AWS account and region combination. Before checking anything else, write down the region your application will actually call. A console screenshot from another region can be entirely correct and entirely irrelevant.

As of October 2026, AWS’s sandbox documentation lists a maximum of 200 messages per 24 hours and one message per second in the sandbox, with recipients restricted to verified identities or the mailbox simulator. Leaving the sandbox removes the verified-recipient restriction. It doesn’t remove sender verification or assign unlimited capacity.

AWS’s quota guide clarifies that sending quotas count recipients rather than API calls. A message with several To, CC, and BCC addresses consumes several recipient units. Record both the daily quota and the maximum sending rate in your readiness review.

Treat a region change as a migration. Check identities, configuration, feedback destinations, permissions, access, and quotas in the destination. Don’t assume an alternate endpoint is a safe fallback after an uncertain request: the original region may already have accepted the message.

Verify a sending identity without breaking existing mail

Use provider-issued DNS records for the exact identity you’re setting up. Don’t copy selectors or tokens from a tutorial. Keep a record of which application and environment owns each sending domain or subdomain.

DKIM, SPF, and DMARC do related but different jobs. DKIM authenticates a signature domain. SPF authenticates the envelope sender’s domain. DMARC checks whether at least one passing mechanism aligns with the visible From domain. AWS explains that relationship in its DMARC guide.

Two practical consequences follow. First, an SPF pass on a provider’s default envelope domain is not automatically an aligned SPF pass for your visible From domain. Second, aligned DKIM can provide the passing mechanism for DMARC without pretending the envelope domain is yours.

Don’t replace the domain’s existing MX records just to send through SES. MX directs incoming mail; outbound domain authentication is a different concern. A custom MAIL FROM setup may have its own subdomain records, but that’s not an instruction to move the company’s existing inboxes.

Also preserve an existing DMARC policy. If an organization already uses enforcement, inventory legitimate senders and alignment before changing it. A generic “paste this p=none record” instruction can weaken a policy that was working correctly.

The review evidence should be one real, authorized test message’s authentication results, not merely the presence of DNS text. That still won’t establish inbox placement for all recipients.

Separate deployment access from application permission

The application needs permission to send appropriate mail, not administer the AWS account. AWS’s SES identity and access management guide describes restricting sending actions, permitted identity ARNs, and From addresses separately from administrative actions. Use those boundaries to define the runtime role; don’t copy a full-access example as its default.

Define the sender identities, region, and application role before creating runtime credentials. Use your platform’s workload identity mechanisms where available; otherwise choose narrowly scoped credentials with an explicit storage and rotation plan. Never put management credentials in frontend code or use a root session as the application’s runtime identity.

Review the effective policy rather than the policy name. A role called “email sender” can still have broad permissions. Conversely, an apparently narrow policy can block a required configuration-set association and leave the application failing after DNS verification succeeded.

For each environment, document who may deploy code, who may change provider configuration, and who can disable sending. Those permissions needn’t belong to the same person or principal. The emergency stop should not require finding the laptop used during initial setup.

Keep a readiness evidence record

Retain one record per control, such as domain authentication or feedback ingestion. Copy this worksheet into your change review; mark unchecked items “not verified” rather than giving them a check because configuration exists.

Record field What to retain
Owner Named responder, backup, and alert destination
Account / region Exact target; identify global controls explicitly
Last verified UTC time, verifier, and result; “not verified” until checked
Evidence Link to saved effective policy, message authentication results, event record, or test report
Stop condition Observable failure, who pauses sending, and where that pause is applied

For feedback ingestion, evidence should connect an authorized test send to a durably handled event. The stop condition should state how missing feedback is detected and who acts. Choose and record a detection window appropriate to the workflow; a silent endpoint with no incoming traffic isn’t, by itself, proof of an outage or proof of health.

Make feedback an explicit dependency

Feedback needs an owner and a durable destination before real application traffic begins. AWS says a bounce and complaint management system is required, and describes the notification mechanisms.

For application-correlated events, choose the configuration set and event destination deliberately. Ensure the send path consistently applies the intended configuration set. An event destination that exists but isn’t selected by your messages is a particularly quiet failure.

For an HTTPS SNS destination, validate signatures before processing notifications or confirmations. Pin the expected topic as well. AWS’s SNS verification guidance explicitly warns against unexpected topic ARNs and unvalidated certificate URLs.

Then decide what each event changes. A permanent bounce should stop repeated sends to that recipient. A complaint should affect future sending policy. A delivery event should update the attempt without erasing a complaint received earlier. Duplicate notifications should be harmless.

These decisions belong in the production review even if the first dashboard only shows a message ID. See the feedback and suppression design for the state model, including why provider suppression doesn’t replace application policy.

An evidence matrix maps each failure scenario to the observable result required before rollout, including duplicates, feedback outages, and uncertain acceptance.

Review the application’s behavior under failure

The most useful readiness questions concern the moments when nobody gets a clean answer.

Scenario Evidence to require
Two requests share one remaining recipient unit Only one reserves capacity
The client repeats the same business send A stable idempotency key identifies the original attempt
Provider response disappears after submission Attempt remains uncertain; no blind redispatch
A signed complaint arrives twice One durable policy change, no duplicate side effects
A delivery event arrives after a complaint Complaint is not overwritten
Event ingestion stops working Monitoring detects the loss and an owner responds

An application queue doesn’t answer these questions automatically. It can make delivery work durable, but a retried job still needs to distinguish “not attempted” from “possibly accepted.” A generic retry-on-exception wrapper doesn’t know that distinction.

Keep the application’s business event separate from each provider attempt. That lets you explain whether a payment receipt was requested once, attempted once, and later reconciled, rather than inventing a new receipt every time a worker restarts.

For a queue-backed workload, also define expiry. A password reset delivered after its token expires is not a successful user experience, even if the mail transport did its job. A weekly digest and a login link shouldn’t share a single retry policy merely because both are email.

Test adverse outcomes before increasing traffic

The SES mailbox simulator provides success, bounce, complaint, and suppression scenarios. Use it to exercise your actual application path, not a direct console send that bypasses the code you’re trying to validate.

There are details worth knowing before writing the test plan. Simulator messages remain billable and subject to the maximum sending rate, though AWS says they don’t consume the daily sending quota or affect reputation metrics. The bounce simulator doesn’t add its address to the SES suppression list. Your own application’s suppression behavior needs separate verification.

Define the expected result before running a test: provider acceptance, durable event correlation, message outcome, recipient policy, and the refusal of a subsequent suppressed send. “The webhook returned 200” only verifies the transport acknowledged a request.

Follow simulator tests with a small, explicitly authorized send to an address you control. Inspect authentication, provider feedback, and the application’s retained outcome. Don’t turn a production review into a list-cleaning exercise against addresses that never asked to receive your tests.

Roll out one workflow with a stop condition

Choose a narrow workflow, a conservative rate, and an owner watching the results. Write down when you’ll pause: lost feedback, unexpected bounces, duplicate business events, unexplained quota usage, or a provider health change.

Keep old and new provider attempts distinguishable during migration. If an attempt is uncertain on one path, don’t “fail over” by immediately sending the same message through another. Preserve suppression records across the cutover. Rollback should change future routing, not replay every message whose status is inconvenient.

This is also where you decide whether to own the stack at all. SendHog, which we build, packages domain setup, sending credentials, recipient accounting, signed provider feedback, and suppression handling over SES. Its quickstart describes setup; the API reference specifies key permissions and responses, and the sending guide distinguishes accepted messages from confirmed receiving-server delivery. Those public contracts help check product fit, not prove reliability. You still own DNS, consent, business-event identity, and useful content.

Direct SES remains a good fit for a team with an established AWS platform and the capacity to operate these controls. A different ESP may have the workflow or support arrangement you need. The architecture comparison helps make that ownership choice before setup work hardens into a permanent obligation.

Primary sources reviewed October 19, 2026. Provider capabilities and pricing can change.

Discuss this post:Hacker NewsShare on XShare on LinkedIn

Related posts