Sending engine Distributed across many machines, many IPs

Many mailboxes.
Many workers. Many IPs.

Not a glorified SMTP relay. The control plane decides what to send. Workers spread sends across machines and IPs so no single point becomes a reputation liability.

Anatomy

The engine, end to end.

Every component, every link. The backend never talks to a mailbox provider directly. Workers never read from Postgres. Each plane has one job and stays in its lane.

architecture · v3 backend → kafka → workers → providers → receivers
CONTROL PLANE EXECUTION PLANE RECEIVERS Backend (REST) cmd/backend Postgres campaigns · contacts · auth Consumer cmd/consumer KAFKA worker.commands.* worker.results.* tracking.events deliverability worker-01 192.0.2.14 · 7 mailboxes + Redis · KMS · S3 worker-02 192.0.2.28 · 8 mailboxes + Redis · KMS · S3 worker-03 192.0.2.42 · 9 mailboxes + Redis · KMS · S3 worker-04 192.0.2.56 · 10 mailboxes + Redis · KMS · S3 Gmail API OAuth · refresh tokens → Gmail · Outlook · receivers Graph API OAuth · refresh tokens → Gmail · Outlook · receivers SMTP / IMAP OAuth · refresh tokens → Gmail · Outlook · receivers iCloud / Zoho OAuth · refresh tokens → Gmail · Outlook · receivers
Control plane
Owns Postgres. Decides assignment. Never sends mail.
Kafka spine
Per-worker command + result topics. Replayable.
Execution plane
Disposable workers. One IP each. No SQL connection.
Trace a single send

318ms from queue to 200 OK.

One message, every handoff. Latencies here are illustrative for a Gmail send on a warm worker. Real traces are visible in the per-mailbox event view.

trace · msg_01HQX9F7P3A8KY2NJM4R6BWT0S mailbox: [email protected] · worker: w-01
T+0ms
backend
queue
campaign_scheduler picks recipient · checks per-mailbox cap (47/100) + gap (last send 11m ago > 10m)
T+4ms
backend →
kafka
publishes send command to worker.commands.w-01 with message envelope + mailbox creds reference
T+8ms
→ worker
consume
worker w-01 consumes command, fetches OAuth refresh token from KMS-cached DEK, builds RFC 5322 message
T+121ms
provider
oauth
refresh access token from Google identity service
T+312ms
gmail api
smtp send
POST users.messages.send → 200 OK · returns gmail message id 18f3a2b9c1
T+318ms
← worker
ack
worker publishes send-result event to worker.results.w-01 · cap usage incremented to 48/100
T+326ms
consumer
persist
consumer folds result into campaign state · contact moves to "sent" status
total: 326ms · 7 handoffs · 1 provider call delivered
Scaling

Volume scales by adding mailboxes.

Not by cranking a few. Each scenario keeps every mailbox at the default cap. When one worker fills with mailboxes, the next worker takes the next batch.

Founder · 1 mailbox
1
mailboxes
1
workers
100
cold / day

A single [email protected] runs on one worker. Default 100/day cap. Plenty of headroom on the worker for warmup partners.

Sales team · 10 mailboxes
10
mailboxes
1
workers
1,000
cold / day

Right at the per-worker concentration warning. One worker carries all 10 mailboxes; healthy as long as no mailbox drifts.

Agency · 50 mailboxes
50
mailboxes
5
workers
5,000
cold / day

Spread across 5 workers so each holds ~10. Concentration warnings never fire. Adding mailboxes triggers a new worker, not a denser one.

Providers

Native Gmail. Native Outlook. SMTP for the rest.

Gmail · OAuth 2.0
Google Workspace

Gmail API for send. Threaded replies preserved via In-Reply-To and References. Postmaster Tools surfaced where the domain is enrolled.

Outlook · OAuth
Microsoft 365

Graph API for send with shared-mailbox support. IMAP and EWS for sync. Tenant-scoped admin consent.

BYOS · TLS
Custom SMTP / IMAP

Bring your own server. TLS, STARTTLS, app passwords, and OAuth where the provider supports it. iCloud and Zoho work first-class.

FAQ

Four engine questions.

Mailboxes are pinned to a worker on first connect and stay there for stability. The control plane can rebalance live by moving the mailbox to a different worker without dropping campaigns or warmup.

Worker state is disposable. A replacement worker reads pending commands from the same Kafka topic on boot and resumes. No mailbox is stuck waiting on a single host.

No. A mailbox lives on one worker with one IP at a time so receiver reputation can stabilise. Migration changes the IP intentionally and is logged.

The per-mailbox 600-second gap is enforced server-side. Even if a campaign queues 100 sends at once, dispatch is rate-limited to the gap, not the queue size.

Connect a mailbox. Send your first campaign today.

OAuth in 30 seconds. Worker assignment is automatic.