Chapter 4
The operational concerns that separate a prototype from production: making sends reliable with retries and idempotency, the metrics that matter, knowing when email alone isn't enough, and deciding whether to build or buy.

Last updated: June 2026
Sending one email is a weekend project. Running a transactional email system that stays reliable, observable, and ready to scale is what takes real engineering. This chapter covers the operational concerns that separate a prototype from production: making sends reliable, measuring what matters, knowing when email alone isn't enough, and deciding whether to build or buy.
In production, email sends fail intermittently: a provider has a blip, a network request times out, your process crashes mid-send. Reliability means handling those failures without losing email and without sending duplicates, and the two tools for that are retries and idempotency.
Retries handle transient failures. When a send fails with a temporary error, you try again, ideally with exponential backoff (wait 1 second, then 2, then 4) so you don't hammer a struggling provider. A durable queue in front of your sends makes this dependable: enqueue the send, process it with a worker, and let the queue redeliver the job if the worker dies.
Idempotency keeps retries from causing duplicates. If your worker sends an email and then crashes before recording success, a naive retry sends the email twice, and now your user has two password reset codes and no idea which is real. An idempotency key solves this: you attach a unique key to each logical send, and the provider (or your own dedup layer) ignores a second request with the same key.
async function sendWithRetry(message, idempotencyKey, maxAttempts = 3) {for (let attempt = 1; attempt <= maxAttempts; attempt++) {try {// The idempotency key ensures a retried request never sends twicereturn await emailProvider.send(message, { idempotencyKey });} catch (error) {if (!error.isTransient || attempt === maxAttempts) {throw error;}const backoffMs = 2 ** (attempt - 1) * 1000;await new Promise((resolve) => setTimeout(resolve, backoffMs));}}}
Derive the idempotency key from something stable about the event, like password-reset:${userId}:${requestId}, rather than generating a random one per attempt. That way every retry of the same logical send carries the same key, and the duplicate is caught.
Key takeaway: Retries without idempotency are worse than no retries. A random key per attempt defeats the whole mechanism. Always derive the key from the event, not the attempt.
Transactional email often carries the keys to an account: reset links, login codes, verification tokens. That makes it a security surface, not only a delivery problem, and a few rules keep it from becoming a liability.
None of this is exotic, but it's the part teams skip when they treat transactional email as plumbing. The messages that matter most for reliability are usually the same ones that matter most for security.
You can't operate what you can't see, so instrument your transactional email from day one. The metrics that matter fall into five groups, and most ESPs expose the first four through dashboards and webhooks. The fifth, business impact, you have to connect yourself, and it's the one that tells you whether the email is doing its job.
| Category | Key metrics | Healthy target |
|---|---|---|
| Delivery | Delivered rate, bounce rate, rejection rate | Delivered 98-99%+, hard bounce <0.5%, soft bounce <1.5% |
| Deliverability | Inbox placement, spam-folder rate, spam-complaint rate | Spam complaints <0.3% (ideally <0.1%) |
| Engagement | Open rate, click rate, time to open | Directional; investigate sudden drops |
| Technical health | Send latency, API error rate, queue depth, retry rate | Time-critical sends in seconds, low error rate |
| Business impact | Action-completion rate, support deflection, revenue influenced | Trending up over time |
Delivery and deliverability are your reputation early-warning system. Keep your delivered rate at 98-99% or higher; a drop usually points to authentication, list-hygiene, or blocklist problems. Keep hard bounces under about 0.5%, and keep your spam-complaint rate below 0.3% (and ideally under 0.1%), because crossing Gmail's threshold throttles your delivery fast. Inbox placement is the metric that actually matters: a 99% delivered rate means nothing if half of it lands in spam.
Engagement matters less for transactional email than for marketing email, but it's not noise. A sudden drop in open rate is often the first sign you've started landing in spam, before the complaint numbers catch up.
Technical health is the part only you can see, so set alerts on it. Watch send latency closely for time-critical email like login codes, because a slow send is a failed send from the user's point of view. Queue depth and retry rate tell you your pipeline is backing up before your users do.
Business impact is where it's easy to stop short, and it's what separates a metric you watch from a metric that earns budget. Tie each email to the action it exists to drive: for a password reset, the real number is how many recipients successfully reset, not how many emails you sent. For a receipt, it's how many "where's my receipt?" support tickets you avoided. For a failed-payment notice, it's recovered revenue. These numbers connect your email system to outcomes the rest of the business cares about, and they're the ones worth putting in front of leadership.
Open tracking works by embedding an invisible pixel in your email. When the recipient opens the message, the pixel loads, and that load is what tells you the email was opened. Click tracking works similarly, by routing your links through a redirect that records the click. Both are how you get the open and click rates from the metrics above.
That mechanism is now under regulatory scrutiny in parts of Europe. In 2026, two data protection authorities, France's CNIL and Italy's Garante, published guidance that treats the tracking pixel like a cookie: something that accesses the recipient's device and therefore needs consent before it fires. Both rest on the EU's ePrivacy Directive, implemented in national law. This is the one area of transactional email where "send the message" and "measure the message" have legally split apart.
The key distinction: sending and tracking are separate. These rules don't stop you from sending the email. You can still deliver a receipt, a password reset, or a shipping update to someone who hasn't consented to tracking. What you can't do is fire the tracking pixel for that send, so you won't know whether they opened it. Compliance here means withholding the pixel, not the email.
This is narrow, and the scope matters, so don't over-correct. Both measures come from national implementations of the EU ePrivacy Directive, so they apply based on where the recipient is, not where your company is headquartered.
If your entire audience is in the US, these rules don't reach you, and you can keep tracking as you do now. The gotcha is the cross-border case: a US-based company that emails recipients in France or Italy is in scope for those recipients. Being legally in scope and being realistically enforced against are different things for a company with no EU presence, but the safe reading is that the obligation follows the recipient.
Both authorities start from the same premise (a pixel needs consent for marketing, profiling, or performance measurement) but differ in force and timing.
| Dimension | France (CNIL) | Italy (Garante) |
|---|---|---|
| Type | Recommendation (best-practice guidance) | Binding provision (Provision No. 284) |
| Consent needed for | Tracking used for marketing, performance, profiling, or fraud detection | Individual-level tracking for marketing, profiling, or campaign performance |
| When to collect consent | At the point you collect the email address | At the point you collect the email address |
| Existing contacts | Inform and offer an easy opt-out by July 14, 2026 | Six-month transition window closing October 28, 2026 |
| New contacts | Compliant consent from April 14, 2026 onward, no transition | Compliant consent from the rules taking effect, no transition |
| Withdrawal | As easy to refuse as to accept, typically a footer link | Easy, selective withdrawal without unsubscribing |
A subtle but important point from the CNIL guidance: consent to tracking is independent of consent to send. You might have a valid basis to email an existing customer and still need separate consent before dropping a tracking pixel in that email.
The exemptions are narrow, so read them strictly before relying on one. Consent generally isn't required when the pixel is used only for:
The word "strictly" carries weight. The moment a pixel feeds marketing performance, profiling, or campaign optimization, you're back in consent territory.
If you have recipients in France or Italy and you use open or click tracking, the practical work is roughly the same regardless of which rule applies:
Watch out: An email address doesn't tell you where a recipient actually lives, so applying tracking rules only to the people you think are in France or Italy is unreliable. The cleaner move is usually an audience-wide decision: default tracking off and turn it on with consent, rather than trying to detect who's European.
When you stop tracking part of your audience, your open and click rates are calculated over fewer tracked sends. That's expected, not a bug. The honest way to read engagement after you adopt consent-based tracking is to compare tracked sends against tracked sends, rather than expecting the same absolute numbers you saw when you tracked everyone. The caution above about open rate being directional applies double here.
Whatever tool you send with, the capability you need is the same: control the tracking pixel per recipient based on a stored consent signal, while still delivering the email. Some platforms expose a per-send tracking override you can flip based on a consent attribute; others offer a workspace-level consent mode that every send respects automatically. If you send with Courier, you can store consent as a user attribute and set a per-send tracking override, using the preference center as the place recipients grant and withdraw it. The mechanics differ by tool; the model (send always, track only with consent) does not.
This section is informational and isn't legal advice. Whether these rules apply to you, and how to configure your sending to meet them, depends on your audience and your use of tracking. Confirm your obligations for the jurisdictions your recipients are in.
Email is the right default for most transactional messages, but it isn't always the fastest or most reliable channel, and some messages need to reach people who aren't checking their inbox. That's when you reach for SMS, push, or in-app notifications alongside email.
The channel should match the message. A login code or fraud alert often belongs on SMS or push, because it's time-critical and email latency is unpredictable. A comment notification might live best as an in-app notification with email as a backup. A receipt is fine as email, since people expect to find it there later. Going multi-channel introduces new problems: you have to respect each user's channel preferences, avoid sending the same notification four ways, and coordinate fallback logic (try push, fall back to email if it isn't delivered). This is the point where you stop thinking in terms of "sending email" and start thinking in terms of "sending notifications" across whatever channel fits, which changes how you architect the whole system.
One option sits underneath all of these: running your own mail server (Postfix or a similar SMTP stack on your own IPs) instead of sending through a provider. It's worth understanding why most teams shouldn't.
The appeal is real: total control and the lowest possible per-message cost at very high volume. But you take on everything a provider otherwise handles for you:
For all but the largest, most specialized senders, that's a full-time job for several engineers and rarely pays off against a provider doing it at scale. So the realistic decision for almost everyone isn't "self-host vs. provider," but which point on the provider spectrum below to choose.
By now the scope is clear: providers, authentication, templates, localization, deliverability, suppression lists, retries, idempotency, metrics, and eventually multiple channels. The real build-versus-buy question isn't whether you can build it, but whether maintaining it is a good use of your engineering time.
It helps to think of this as a spectrum rather than a binary, because you don't have to choose between "raw ESP" and "buy everything." There are three points along it:
There's no universally correct answer, and the honest version of the trade-off is about trajectory, not today. If email is all you'll ever send and you have the engineering capacity to maintain it, building on an ESP directly is fine. The moment you're juggling multiple channels, user preferences, and a growing template library, that homegrown abstraction layer from option 2 is usually the most expensive thing your team maintains, and the math starts favoring infrastructure. The useful question isn't "build or buy?" but "how much of this layer do I want to own a year from now?"
Transactional email rewards getting the fundamentals right and punishes treating it as an afterthought. If you take away a handful of things from this guide, make it these.
Know what you're sending: transactional email is event-driven, one-to-one, and expected, which is what earns it inbox placement and exempts it from most marketing rules. Get the foundation right before anything else: authenticate with SPF, DKIM, and DMARC, send from a real domain, and keep transactional mail on its own stream. Choose a provider that fits your volume and stack, and lean on its API rather than raw SMTP. Build for production from the start with templates, fallbacks, retries, idempotency, and a suppression list wired to your bounce and complaint webhooks. And measure continuously, watching delivery, deliverability, engagement, and technical-health metrics so you catch problems before your users do.
Start with one email done properly, a password reset or a receipt, with authentication, a clean template, and error handling in place. Get that landing reliably in the inbox, then expand. When you outgrow a single channel or a single ESP, that's the signal to evaluate notification infrastructure that can carry the same rigor across email, SMS, push, and in-app.
Inbox placement rate, because it measures whether your email actually reaches users where they'll see it. Delivery rate can look high while messages quietly land in spam. After placement, track the action each email exists to drive, like password-reset completion, rather than opens.
Open tracking relies on a pixel, and privacy features like Apple Mail Privacy Protection pre-load that pixel whether or not the user opens the message, which inflates reported opens. Treat open rate as a directional trend and lean on click-through and task completion for accuracy.
It depends on where your recipients are. As of 2026, France's CNIL and Italy's Garante require consent before firing a tracking pixel for marketing, profiling, or performance measurement, and both rules follow the recipient's location rather than your company's. If your recipients are outside France and Italy, these two rules don't apply. Either way, consent affects tracking, not sending: you can still deliver the email without the pixel. See the section on handling email open-tracking consent above for the deadlines and remediation steps.
For almost all teams, build on an email service provider rather than running your own mail server. Whether you then add a thin abstraction layer or adopt notification infrastructure depends on trajectory: once you're juggling multiple channels, user preferences, and a growing template library, infrastructure usually costs less than maintaining that layer yourself.
| Term | Definition |
|---|---|
| Transactional email | An automated, one-to-one message triggered by a user action or account event, like a password reset or receipt. |
| Marketing email | Promotional content sent on your schedule to a list of recipients, requiring explicit opt-in and an unsubscribe option. |
| SMTP (Simple Mail Transfer Protocol) | The standard protocol that moves email between servers. |
| ESP (email service provider) | A service that sends your email and works to keep it landing in the inbox, handling IP reputation, bounces, and deliverability. |
| SPF (Sender Policy Framework) | A DNS record listing the servers allowed to send email for your domain. |
| DKIM (DomainKeys Identified Mail) | A cryptographic signature added to each message so receivers can verify it wasn't altered in transit. |
| DMARC (Domain-based Message Authentication, Reporting, and Conformance) | A DNS record that tells receivers what to do when a message fails SPF or DKIM, and where to send reports. |
| BIMI (Brand Indicators for Message Identification) | A standard that displays your logo next to authenticated messages in supporting inboxes. |
| VMC (Verified Mark Certificate) | A certificate that verifies logo ownership, usually required for BIMI. |
| Deliverability | The likelihood that your email reaches the inbox rather than the spam folder or the void. |
| Inbox placement rate | The percentage of sent email that lands in the inbox specifically, not just the percentage accepted by the server. |
| Tracking pixel | An invisible image embedded in an email that loads when the recipient opens the message, recording the open. Some jurisdictions now require consent before it fires. |
| Idempotency key | A unique identifier attached to a send so a retried request never delivers the same email twice. |
| Suppression list | A list of addresses you never send to again because they hard-bounced or filed a spam complaint. |
| i18n (internationalization) | Designing your email system so it can send the right language and regional formatting to each recipient. |
| CDP (customer data platform) | A system like Segment or RudderStack that routes product events to your email layer and other tools. |
Related resources:
© 2026 Courier. All rights reserved.