01 — Outbound Infrastructure

How to Design an Outbound System

Most outbound teams start with the wrong question:

"How many emails can we send?"

That question leads directly to more inboxes, more domains, more automation — and eventually, more problems.

A better question is:

"What system do we need to consistently reach the right prospects without degrading the infrastructure that makes future outbound possible?"

Outbound is not just a sequence of emails sent from a collection of sales accounts. It's a system made of identity, domains, mailboxes, authentication, data, routing, sending controls, and feedback loops. Design those components independently, and outbound stays fragile no matter how much you automate it. Design them as one system, and outbound becomes something you can actually scale.

What an Outbound System Actually Is

An outbound system is the infrastructure that turns a prospect list into controlled, measurable communication. At a high level, it has six components:

  1. Identity — who is sending the message

  2. Domain architecture — where that identity lives

  3. Sending infrastructure — which mailboxes and providers send the messages

  4. Data layer — who should receive the messages, and why

  5. Control layer — how volume, routing, and failures are managed

  6. Observability — how the system knows whether it's healthy

A useful mental model:

Prospects → Data → Routing → Sender → Message → Mailbox Provider → Reputation → Feedback

The message is only one layer of that chain. Treating it as the whole system is the mistake that causes most outbound programs to break once they scale past a handful of mailboxes.

1. Start With the Objective, Not the Tools

Before buying domains or configuring mailboxes, define what the system needs to accomplish: generate qualified conversations, reach a specific ICP repeatedly, support multiple markets, run several motions at once, increase capacity without damaging sender reputation, or maintain continuity when a sending asset goes down.

These objectives determine the architecture, not the other way around. A system built for 500 highly targeted prospects a month shouldn't look like a system built for a million commercial messages. A system supporting one market shouldn't be copy-pasted across five regions without accounting for differences in language, domain history, data quality, and which mailbox providers dominate each region.

2. Design the Identity Layer

Every outbound message needs a credible identity — and that identity is more than the name in the From field. It includes the sending domain, the From address, the mailbox itself, the reply-to identity, authentication records, domain reputation, and sending history.

This is why "just create more inboxes" is a weak scaling model. A mailbox doesn't exist in isolation — its behavior feeds into a larger reputation environment shared with every other mailbox on that domain.

Fact: Google requires all senders to authenticate with either SPF or DKIM, and requires bulk senders (roughly 5,000+ messages/day to Gmail) to configure SPF, DKIM, and DMARC together.

Architectural principle: sender identity should be treated as infrastructure to be designed, not as a per-account setting to be toggled on later.

3. Build Domain Architecture Before Mailbox Architecture

A common mistake is deciding how many mailboxes to buy before deciding how domains are structured. Start with domains instead. A domain architecture should answer:

  • Which domains represent the company?

  • Which domains are used purely for outbound?

  • Which domains support other email streams (transactional, marketing, corporate)?

  • Which identities belong to which outbound motion?

  • How is reputation isolated between them?

  • What happens if one sending environment develops a problem?

Fact: Google's own sending-practices guidance recommends that messages of the same category share the same From address — for example, sales-receipt mail from sales@, promotional mail from deals@, and account-notification mail from alert@ — rather than mixing categories on one identity.

Architectural principle: separate concerns (transactional vs. marketing vs. cold outbound) before you try to scale any one of them. Mixing categories on shared infrastructure means a spike in complaints from one motion can damage deliverability for all of them.

4. Establish Authentication as a Foundation

Before scaling volume, establish the authentication baseline. At minimum:

  • SPF lets receiving servers verify which IPs are authorized to send on behalf of a domain.

  • DKIM attaches a cryptographic signature so receivers can verify a message wasn't altered and was authorized by the signing domain.

  • DMARC ties authentication back to the visible From domain and gives the domain owner a policy and reporting mechanism.

Fact: as of February 2024, Google requires all senders to Gmail personal accounts to have SPF or DKIM configured, and requires senders of 5,000+ daily messages to have SPF, DKIM, and DMARC configured together, with the From-header domain aligned to the authenticating domain. Yahoo introduced a parallel — but not identical — set of requirements on the same timeline: DMARC with at least a p=none policy, and SPF or DKIM aligned to the From domain, though Yahoo does not publish the same explicit volume threshold Google uses.

That last point matters architecturally: mailbox-provider requirements are not identical. Gmail and Yahoo have both tightened sender rules in recent years, but their exact thresholds and enforcement mechanics differ, and Microsoft and Apple have layered on their own variations. A robust outbound architecture treats "provider requirements" as external, shifting constraints to monitor — not as a single fixed spec to design around once and forget.

Architectural principle: don't scale a sending system that hasn't established its authentication baseline first. Adding volume to a misconfigured system doesn't make it stronger — it makes the failure bigger and harder to trace.

5. Design the Data Layer Separately

Outbound infrastructure is only as good as the data entering it. The system should distinguish at least three things:

Identity data — who the prospect is: name, company, role, email, profile identifiers, location.

Qualification data — why this person should receive outbound at all: ICP fit, company size, industry, tech stack, trigger events, buying signals. For example, "posted a job for a role our product replaces" is a trigger event; "uses a competitor's tool per BuiltWith" is a fit signal — these are different fields serving different filtering logic downstream.

Operational data — how the system should treat this specific prospect right now: campaign, segment, assigned sender, sequence step, last-contact date, reply status, bounce status, suppression status.

This separation matters because data drives routing. If the system can't answer why a prospect belongs in a campaign, it can't intelligently decide who should send to them, when, or when they should be pulled out. A prospect who bounced once should route differently than one who replied "not now" — but only if bounce status and reply status are tracked as distinct operational fields rather than collapsed into a single "engaged/not engaged" flag.

6. Introduce a Routing Layer

Once identities and data exist, you need routing logic to connect them. Routing answers: which sender should contact this prospect? Which campaign should they enter? Which domain should be used? What happens if the assigned sender is unavailable?

A basic model:

Prospect → Segment → Campaign → Sender Pool → Mailbox → Message

A more resilient model adds health signals:

Prospect → Segment → Eligible Sender Pool → Healthy Mailbox → Send

The word eligible matters. A mailbox shouldn't be selected just because it has spare capacity — it should be selected because it satisfies the system's rules: correct market, correct sender identity, correct campaign, sender currently healthy, domain healthy, within daily limits, no recent failure condition, prospect not suppressed. That's what turns "automation" into "controlled routing" — the difference is whether a failure condition can actually stop a send, not just log it.

7. Add Sending Controls

The next layer is capacity management: sending volume, velocity, sending windows, per-mailbox limits, per-domain limits, provider limits, campaign limits, and error thresholds.

The objective isn't maximizing today's send count — it's maximizing sustainable output over time. This is one of the few places where the underlying infrastructure enforces the principle whether you design for it or not.

Fact: for Amazon SES dedicated IPs, AWS's automatic warm-up process gradually increases the maximum daily send volume over a fixed 45-day period, independent of how much volume you'd like to send — because ISPs interpret a sudden jump in volume from a new IP as a signal of abuse, and will throttle or drop mail in response.

Architectural principle: capacity should be introduced progressively as a designed process, not assumed to exist simply because the sending infrastructure is technically capable of higher volume. This applies beyond IP warm-up — it's the same logic behind gradually ramping a brand-new domain or mailbox before pointing a full campaign at it.

8. Design for Failure

A production outbound system should assume components will fail: domains developing reputation problems, mailboxes going down, providers throttling, APIs failing, data going stale, campaigns generating abnormal bounce or complaint rates. The goal isn't to improvise when that happens — it's to have failure states designed in advance:

  • Healthy — normal sending.

  • Degraded — sending continues at reduced capacity.

  • Suspended — the affected sender or domain stops receiving new outbound traffic.

  • Recovery — the cause is investigated before the asset returns to production.

One distinction that matters as systems grow: failover is not rotation. Rotation distributes traffic across healthy assets for load-balancing reasons. Failover moves traffic away from an asset because it should no longer receive it — a different trigger, and one that needs its own explicit logic rather than being handled by the same code path as rotation.

9. Build Observability Into the Architecture

You can't manage what you can't see. Observability should exist at several levels:

  • Domain level — authentication status, reputation signals, DNS configuration, sending patterns.

  • Mailbox level — volume, delivery errors, bounce behavior, reply activity, authentication status.

  • Campaign level — delivery, replies, positive replies, meetings booked, conversion, bounce rate.

  • Provider level — throttling, deferrals, blocks, provider-specific error codes.

Fact: Google's Postmaster Tools reports domain-level authentication status, spam-rate history, IP/domain reputation, and delivery errors — and Google explicitly recommends monitoring it continuously as volume increases, not just at setup. Google also publishes specific SMTP error codes tied to individual failure types (for example, error 5.7.26 for messages that fail authentication, or 4.7.28 for exceeding a sending quota), which makes it possible to route failures to the specific layer that caused them rather than treating "delivery failed" as one undifferentiated bucket.

That last point is the practical payoff of building observability into the architecture rather than bolting it on afterward: a differentiated error means a differentiated response — a quota error should trigger a cooldown, not a domain suspension.

10. Use Reputation as a System Signal

A common mistake is treating reputation as binary — good or bad. In practice it behaves more like a continuously moving signal that accumulates based on behavior: bounce patterns, spam complaints, delivery errors, engagement, sending consistency, authentication status, and sudden volume changes all feed into it.

Fact: Google's guidance sets 0.3% as the hard ceiling for spam complaint rate reported in Postmaster Tools — senders exceeding this face degraded delivery. Separately, in its monitoring guidance, Google recommends operating below 0.1% and never approaching 0.3% at all, on the reasoning that a lower baseline gives more margin to absorb occasional spikes in complaints without tripping the ceiling.

Architectural principle: reputation should influence routing, not just get reported after the fact. If an asset's health degrades, the system should reduce or stop its traffic automatically rather than continuing to feed it new prospects until a human notices the dashboard.

11. Separate Capacity From Demand

Another common mistake is designing infrastructure around how many prospects you have available, rather than around what output you actually need:

"We have 100,000 prospects, so we need enough mailboxes to reach all of them."

That reverses the relationship. A better model:

Demand → Required throughput → Safe capacity → Infrastructure

If sales needs 20,000 outbound touches a month, the architecture should determine how much healthy sending capacity is required to hit that number sustainably — not back into a mailbox count from the size of the prospect list. Sizing infrastructure to list size instead of to actual required throughput is one of the most common ways teams end up over-provisioned on mailboxes and under-provisioned on reputation management.

12. Design for Expansion

A good outbound system should be expandable without a redesign: new markets, new sender identities, new campaigns, new domains, new providers, new data sources, new routing rules — added without breaking what's already running.

This is where modularity matters. Think in pools rather than individual assets:

Domain Pool → Sender Pool → Campaign Pool → Prospect Pool → Routing Rules

Each layer can then evolve independently — adding a new domain pool for a new market shouldn't require touching the routing rules for existing markets.

13. The Architecture in One Diagram

The system reduces to six layers, connected by a feedback loop back into routing:

BUSINESS GOALS  →  DATA LAYER  →  ROUTING LAYER  →

INFRASTRUCTURE LAYER  →  SEND LAYER  →  OBSERVABILITY LAYER

        ↑___________________________________________|

                    (feedback into routing decisions)


That feedback loop is what makes this architecture a system rather than a pipeline. Without feedback, you have automation running open-loop. With feedback — reputation signals changing routing decisions, error codes changing sending limits — you have infrastructure that can protect itself.

14. A Practical Design Sequence

If building from zero, roughly this order:

  1. Define the operating model — ICP, markets, motions, expected volume, required throughput, sender identities.

  2. Build the identity architecture — domains, mailboxes, provider strategy, authentication requirements.

  3. Build the data layer — prospect sources, qualification rules, segmentation, suppression, validation.

  4. Build routing — sender assignment, campaign assignment, capacity rules, eligibility rules, failover conditions.

  5. Add sending controls — limits, velocity, scheduling, warm-up, error thresholds.

  6. Add observability — authentication, delivery, bounces, complaints, reputation, provider errors, outcomes.

  7. Introduce automation — only once the system works manually. Automation should enforce the architecture, not substitute for it.

The Core Principle

The biggest mistake in outbound infrastructure is optimizing for maximum sending capacity. The better objective is maximum sustainable sending capacity — and those are not the same number.

A system that can send 100,000 emails today but damages its own sending environment in the process isn't scalable, whatever the dashboard says this week. A system that repeatedly generates qualified conversations while protecting its domains, identities, data quality, and reputation is. That's the difference between an outbound tool stack and an outbound system: tools send messages; systems manage the constraints that determine whether those messages get read at all.


Engineering Reviews & Logs
0 ENTRIES