Transactional Email: Definition and Characteristics
Transactional emails are automated, triggered by a specific user action:
- Order confirmation
- Password reset
- Shipping notification
- Account verification
- Payment receipt
- Two-factor authentication codes
Characteristics:
- One-to-one communication (1 recipient per message)
- High individual value, low total volume
- Immediate delivery required (< 30 seconds SLA)
- Highly personalized content
- Must reach inbox — users are waiting for these
- Low complaint risk (user requested it)
SLA requirements:
- 99.9%+ delivery success rate
- < 30 second end-to-end latency
- 24/7 availability (no maintenance windows)
Bulk Email: Definition and Characteristics
Bulk (marketing) emails are one-to-many:
- Newsletters
- Promotional campaigns
- Product announcements
- Re-engagement campaigns
- Retention campaigns
Characteristics:
- One-to-many (single campaign → thousands/millions of recipients)
- High total volume, moderate individual value
- Delivery speed less critical (hours acceptable)
- Campaign-level tracking (open rates, click rates)
- Higher complaint risk (recipients may not have opted in)
- CAN-SPAM and GDPR compliance required
SLA requirements:
- 95%+ delivery success rate
- < 4 hour campaign completion
- List-unsubscribe compliance (RFC 8058)
- Unsubscribe processing within 10 days (CAN-SPAM)
Why Separation Matters
Problem 1: Marketing Traffic Competes With Transactional
If your marketing campaign sends 500K emails over 2 hours, it consumes MTA resources (connections, queue slots, CPU) that your transactional emails need. The result: password resets arriving 10 minutes late.
Problem 2: Reputation Contamination
One bad marketing campaign (high bounce rate, complaints) can damage your IP reputation — which affects your transactional emails' inbox placement.
Problem 3: Compliance Conflicts
Marketing email requires List-Unsubscribe headers (RFC 8058) and opt-out mechanisms. Transactional email doesn't. Mixing them in one queue creates compliance complexity.
Problem 4: Monitoring Complexity
Blending transactional and bulk metrics makes it impossible to know if your transactional deliverability is healthy.
Architecture: Separate MTA Stacks
Recommended Architecture for 5M+/month Senders
┌─────────────────────────────────────────────────────────┐
│ Application Layer │
│ (Orders, Auth, Marketing Platform, CRM) │
└──────────────────────┬──────────────────────────────────┘
│
┌─────────────┴──────────────┐
│ │
┌────────▼─────────┐ ┌──────────▼──────────┐
│ Transactional │ │ Bulk/Marketing │
│ SMTP Relay │ │ SMTP Relay │
│ (KumoMTA-1) │ │ (KumoMTA-2) │
│ │ │ │
│ - High priority │ │ - Normal priority │
│ - 2s SLA │ │ - 4h campaign SLA │
│ - Separate IPs │ │ - Separate IPs │
│ - P0 alerting │ │ - P1 alerting │
└────────┬─────────┘ └──────────┬──────────┘
│ │
┌────────▼─────────┐ ┌──────────▼──────────┐
│ Dedicated │ │ Dedicated │
│ IPs (warm, │ │ IPs (warm, │
│ established rep) │ │ separate rep) │
└───────────────────┘ └─────────────────────┘
Separate DKIM and Domains
Transactional:
From: noreply@mx.example.com- DKIM:
mail._domainkey.mx.example.com - Separate reputation for critical sending
Bulk/Marketing:
From: hello@example.com- DKIM:
mail._domainkey.example.com - More tolerant reputation risk
KumoMTA Configuration: Transactional vs Bulk
Transactional Configuration (High Priority)
-- /etc/kumomta/transactional.conf
-- High-priority SMTP listener
kumo.start_smtp_listener {
listen = "[::]:2525",
name = "transactional",
relay_hosts = { "10.0.0.0/8" },
auth_require_tls = true,
}
-- Prometheus metrics (separate port)
kumo.start_http_listener {
listen = "[::]:2001",
trusted_hosts = { "127.0.0.1" },
}
-- Minimal queue depth for low latency
kumo.configure_queue {
max_queue_depth = 5000,
retry_interval = "1m",
max_retry_age = "24h",
}
-- DKIM signing
kumo.configure_dkim_signing {
domain = "mx.example.com",
selector = "mail",
key_file = "/etc/kumomta/keys/mail._domainkey.mx.example.com.pem",
}
Bulk Configuration (Normal Priority)
-- /etc/kumomta/bulk.conf
-- Bulk/marketing listener
kumo.start_smtp_listener {
listen = "[::]:2526",
name = "bulk",
relay_hosts = { "10.0.0.0/8" },
auth_require_tls = true,
}
-- Prometheus metrics (separate port)
kumo.start_http_listener {
listen = "[::]:2002",
trusted_hosts = { "127.0.0.1" },
}
-- Higher queue depth for volume
kumo.configure_queue {
max_queue_depth = 100000,
retry_interval = "5m",
max_retry_age = "72h",
}
-- DKIM signing
kumo.configure_dkim_signing {
domain = "example.com",
selector = "mail",
key_file = "/etc/kumomta/keys/mail._domainkey.example.com.pem",
}
-- RFC 8058 List-Unsubscribe headers
kumo.on("smtp_message_received", function(domain, meta)
local headers = meta.headers or {}
-- Only add for bulk campaigns
if headers["X-Campaign-Type"] == "marketing" then
kumo.add_header("List-Unsubscribe",
"<mailto:unsubscribe@example.com?subject=unsubscribe>")
kumo.add_header("List-Unsubscribe-Post",
"List-Unsubscribe=One-Click")
kumo.add_header("Precedence", "bulk")
end
end)
Compliance: CAN-SPAM and GDPR
Transactional Exemption
Key fact: CAN-SPAM exempts transactional emails from:**
- Physical postal address requirements
- Opt-out link requirements (though still recommended)
Transactional exemption applies when:
- Email is to facilitate an existing transaction
- Email is about a purchase or account status
- Email is a one-to-one communication
Marketing emails are NOT exempt:
- Newsletters, promotions, announcements
- Re-engagement campaigns
- Non-triggered educational content
GDPR Considerations
| Email Type | Consent Required | Legitimate Interest |
|---|---|---|
| Transactional | No (contractual necessity) | N/A |
| Marketing (explicit opt-in) | Yes | No |
| Marketing (existing customer) | Yes (soft opt-in in some EU countries) | Sometimes |
| Re-engagement | Yes | No |
For bulk sending to EU residents:
- Explicit consent required before sending
- Double opt-in recommended
- Clear unsubscribe mechanism
- Data minimization (don't retain more than needed)
When NOT to Separate
Separating transactional and bulk infrastructure adds operational complexity. Don't separate if:
- Your total volume is under 500K/month
- Your transactional volume is under 10K/month
- You have no engineering capacity to manage two stacks
- Your marketing and transactional emails come from the same product (e.g., a marketplace where order confirmations ARE your marketing)
In these cases, use a single MTA with traffic shaping to prioritize transactional:
kumo.on("smtp_message_received", function(domain, meta)
local headers = meta.headers or {}
if headers["X-Priority"] == "high" then
kumo.set_queue_priority("high")
end
end)
Monitoring: Separate Metrics for Each
Transactional Metrics Dashboard
| Metric | Target | Alert |
|---|---|---|
| Delivery success rate | > 99.9% | < 99.5% |
| End-to-end latency (p95) | < 30s | > 60s |
| Queue depth | < 100 | > 500 |
| Hard bounce rate | < 0.1% | > 0.5% |
| 5xx error rate | < 0.1% | > 0.5% |
Bulk Campaign Metrics Dashboard
| Metric | Target | Alert |
|---|---|---|
| Campaign delivery rate | > 96% | < 93% |
| Campaign completion time | < 4 hours | > 8 hours |
| Hard bounce rate | < 2% | > 5% |
| Soft bounce rate | < 5% | > 10% |
| Complaint rate | < 0.1% | > 0.3% |
| Unsubscribe processing | < 10 days | > 10 days |
FAQ
Q: Can I use the same domain for transactional and bulk email?
A: Technically yes, but not recommended. If your bulk sending damages the domain's reputation, your transactional emails suffer too. Use subdomains (e.g., mx.example.com for transactional, example.com for bulk).
Q: Should I use separate IP addresses for transactional and bulk?
A: Yes — always. This is the most effective way to prevent reputation cross-contamination. Your transactional IP should have established, pristine reputation. Your bulk IP(s) can absorb more risk.
Q: Can I send transactional and bulk through the same KumoMTA instance?
A: Yes, using Lua policies to route and prioritize differently. But for high-volume operations (10M+/month), separate instances on separate infrastructure provide better isolation.
Q: Does SendGrid/Mailgun separate transactional and bulk?
A: Yes — both have separate APIs and infrastructure for transactional (via SMTP/API) and marketing (via marketing campaigns). This is one reason enterprise senders often migrate to self-hosted KumoMTA for full control.
Q: What's the minimum volume where separation becomes worth it?
A: When your bulk campaigns regularly exceed 100K emails/session, or when transactional SLA < 30s is business-critical. For most organizations, this is around 2-5M total monthly volume.
Get Help With Email Architecture
PostMTA designs email infrastructure for high-volume senders:
- Transactional/bulk separation architecture
- KumoMTA multi-stack configuration
- Compliance audit (CAN-SPAM, GDPR)
- Reputation management and IP strategy
👉 Talk to our infrastructure team →
For related guides, see SMTP Relay Setup Guide, IP Warmup Strategies, and KumoMTA Setup Guide.
References: RFC 8058 (List-Unsubscribe) | CAN-SPAM Requirements
Top comments (0)