How to Set Up KumoMTA on AWS for Production: The Ultimate Enterprise Guide
Quick summary: KumoMTA on AWS production setup: 4 vCPU / 16 GiB baseline per official docs, $200-$610/mo dev footprint, SMTP architecture without ALB, and a 100+ item readiness checklist for self-hosted email infrastructure.
Key Takeaways
- AWS documents the same EC2 port-25 restriction
- As of July 2026, that baseline still defines the minimum viable EC2 shape for engineering teams evaluating self-hosted MTA infrastructure
- This guide is for DevOps engineers, cloud architects, and deliverability specialists building production email infrastructure on AWS
- For managed-ESP paths, see Amazon SES consulting and SES migration
- Artifacts: README, policy skeleton, Route53 DNS template, CloudWatch agent config, readiness checklist

Table of Contents
KumoMTA’s official server environment guide recommends at least 4 vCPUs and 16 GiB RAM for production-bound instances, with an explicit note that most public clouds block outbound port 25 until you request removal. AWS documents the same EC2 port-25 restriction. As of July 2026, that baseline still defines the minimum viable EC2 shape for engineering teams evaluating self-hosted MTA infrastructure.
This guide is for DevOps engineers, cloud architects, and deliverability specialists building production email infrastructure on AWS. For managed-ESP paths, see Amazon SES consulting and SES migration. Many searches use the misspelling “KumaMTA”; the canonical product name is KumoMTA.
Artifacts: README, policy skeleton, Route53 DNS template, CloudWatch agent config, readiness checklist.
Benchmark pattern (not a cited client) — Engineering-led SaaS, mixed transactional + marketing, planning 1M-3M emails/day on a single
c7i.xlargenode aligned to KumoMTA’s 4 vCPU / 16 GiB guidance. Conservative queue concurrency (30-50 connections per major mailbox provider) before vertical scale-out. Development AWS footprint: $200-$610/month (compute + storage + observability baseline in this guide’s cost table).
What broke — Day 2 of a greenfield AWS rollout: marketing traffic rode the same Elastic IP as OTP mail. Google Postmaster complaint rate crossed policy threshold; transactional OTP placement degraded for 72 hours until IP pools were split and marketing sends paused.
Reproduce this — Copy templates from
examples/kumomta-aws-production/. Applypolicy/init.lua.exampleanddns/route53-records.example.txton a non-production domain before routing production traffic.
Executive Summary
KumoMTA on AWS gives engineering-led teams policy-driven queue control, multi-IP reputation isolation, and SMTP path ownership — at the cost of running a persistent email operations program (warmup, complaints, DNS auth, observability).
| Question | Short answer |
|---|---|
| Who needs self-hosted KumoMTA? | SaaS and enterprises sending 1M+ emails/day that need queue policy ownership and AWS-native security integration |
| Who should skip? | Low-volume senders, teams without deliverability ops capacity, SMTP-only stacks unwilling to run policy automation |
| Minimum EC2 shape? | 4 vCPUs, 16 GiB RAM per KumoMTA docs; dedicated instance with tuned EBS gp3 |
| Biggest architecture mistake? | Putting SMTP behind CloudFront/WAF/ALB — SMTP terminates on EC2 + Elastic IP |
| Our recommendation | Use KumoMTA when you need policy automation + IP pool isolation; use Amazon SES when you want managed deliverability with lower ops burden. Hybrid (KumoMTA + SES relay) is valid for phased migration. |
What Is KumoMTA?
KumoMTA is a modern Mail Transfer Agent designed around policy, performance, and automation.
Core Capabilities
| Capability | What It Does | Why It Matters in Production |
|---|---|---|
| Queue management | Maintains message queues by tenant/domain/route | Prevents one noisy stream from degrading all traffic |
| SMTP engine | Handles outbound/inbound SMTP sessions with TLS support | Controls throughput and transport behavior under load |
| Bounce handling | Processes hard/soft bounces and deferred responses | Protects sender reputation and retry efficiency |
| Scheduling | Controls send timing and retry windows | Supports ISP-aware delivery cadence |
| Rate limiting | Limits by destination and policy | Prevents throttle/deferral spirals at mailbox providers |
| Multi-IP support | Routes sends through dedicated/shared IP pools | Enables isolation by traffic class and warmup strategy |
| High throughput | Multi-core optimized message processing | Supports high-volume burst traffic |
| API and policy hooks | Programmatic control via policy definitions | Enables automated operations and custom routing logic |
| Lua automation | Dynamic rules and policy enrichment | Applies business logic at SMTP decision points |
| Policy engine | Defines listener/route/queue behavior | Replaces ad hoc runtime changes with deterministic policy |
Functional Model
flowchart LR
ingress[AppEventsOrSMTPInject] --> policy[PolicyEngineLua]
policy --> queue[QueueManager]
queue --> shaping[RateLimitAndShaping]
shaping --> smtp[OutboundSMTPClient]
smtp --> mx[RecipientMX]
smtp --> events[DeliveryEvents]
events --> analytics[ObservabilityAndFeedbackLoop]Why Choose KumoMTA?
KumoMTA is strongest when you need automation-first operations for complex sending patterns.
Practical Advantages
- Modern architecture: Better fit for API-driven and policy-driven operations than legacy defaults.
- Queue control: Fine-grained queue segmentation and shaping at domain/provider level.
- Automation readiness: Lua and policy controls reduce manual queue firefighting.
- Cloud alignment: Works cleanly with EC2, IAM, CloudWatch, EventBridge, S3, and Security Hub workflows.
- SaaS fit: Easier multi-tenant traffic isolation than many older MTA setups.
Feature Comparison
| Area | KumoMTA | Legacy MTA Pattern |
|---|---|---|
| Policy automation | Strong | Often script-heavy/custom patches |
| Queue shaping control | Strong | Varies by implementation |
| API-friendly operations | High | Moderate to low |
| Multi-IP routing strategy | Strong | Depends on custom config |
| Cloud-native observability integration | Strong | Often bolt-on |
| Operator ergonomics at scale | High | Mixed |
Compare KumoMTA with Popular MTAs
Comparative Matrix
| MTA | Performance | Queue Mgmt | API | Rate Limiting | Multi-IP | Scaling | Deliverability Controls | Licensing | Automation Ease | Enterprise Readiness | Cost Profile | Best Use Case |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| KumoMTA | High | Advanced | Strong | Advanced | Strong | Strong | Strong | Commercial/open components depending edition | High | High | Moderate infra + ops | Engineering-led high-volume sending |
| Postfix | High | Solid | Limited native | Basic-native + external policy | Possible | Strong with ops effort | Good with tuning | Open source | Medium | High | Low software cost | Traditional Linux mail infrastructure |
| Exim | High | Flexible | Limited native | Flexible via ACL/config | Possible | High with expertise | Good with tuning | Open source | Medium | Medium-high | Low software cost | Highly customized mail logic |
| PowerMTA | Very high | Advanced | Strong | Advanced | Strong | Strong | Strong | Commercial | High | High | Higher license + infra | Very high volume sender operations |
| Haraka | Medium-high | Plugin-centric | Good | Plugin-dependent | Possible | Medium-high | Varies | Open source | High | Medium | Low software cost | Node-based custom SMTP logic |
| OpenSMTPD | Medium | Basic-moderate | Limited | Limited | Possible | Medium | Basic | Open source | Medium-low | Medium | Low software cost | Smaller secure mail deployments |
| MailEnable | Medium | Moderate | Moderate | Moderate | Limited | Medium | Moderate | Commercial | Medium | Medium | License + Windows ops | Windows-centric environments |
| Exchange SMTP | Medium | Moderate | Limited for MTA use | Basic | Limited | Medium | Basic for bulk | Commercial | Low-medium | Medium | License + enterprise overhead | Internal enterprise relay scenarios |
| Postal | Medium-high | Moderate | Good | Moderate | Moderate | Medium | Moderate | Open source | Medium | Medium | Low software + infra ops | SMB to mid-market outbound stack |
| Mailcow | Medium | Moderate | Limited for high-volume outbound | Basic | Limited | Medium | Moderate | Open source | Medium-low | Medium | Low software + admin effort | Self-hosted full mail suite |
| ZoneMTA | Medium-high | Good | Good | Good | Good | Medium-high | Good | Open source | Medium-high | Medium | Low software + ops | ESP-adjacent custom sending pipeline |
Recommendation Matrix
| Scenario | Recommended Path |
|---|---|
| SaaS transactional + campaign mix, AWS-first, policy-heavy routing | KumoMTA |
| Traditional Linux mail admin team with low API requirements | Postfix/Exim |
| Maximum high-volume commercial deliverability ops with budget | PowerMTA |
| Smaller footprint, simpler open-source stack | Postal/ZoneMTA |
| Internal enterprise relay only | Exchange SMTP relay |
AWS Production Architecture
A critical design correction: CloudFront/WAF/ALB are not your SMTP data plane. For teams comparing self-hosted MTA vs managed ESP, see Amazon SES Tenant Management and SES Global Endpoints (MREP). They can front HTTPS endpoints (tracking, admin APIs, webhooks), but SMTP traffic must route directly to/from EC2 Elastic IP endpoints.
Reference Architecture Overview
flowchart TD
internet[Internet] --> r53[Route53]
r53 --> cf[CloudFrontForHTTPSOnly]
cf --> waf[AWSWAF]
waf --> alb[ALBForHTTPSAppsOnly]
alb --> api[AdminOrTrackingAPI]
app[SendingApplications] --> inject[SubmissionAPIorSMTP587]
inject --> mta[KumoMTAonEC2WithEIP]
mta --> ses[OptionalAmazonSESHybridRelay]
mta --> recipient[RecipientMXServers]
ses --> recipient
subgraph support [AWSSupportingServices]
cw[CloudWatch]
ssm[SystemsManager]
ct[CloudTrail]
cfg[AWSConfig]
gd[GuardDuty]
insp[Inspector]
sm[SecretsManager]
kms[KMS]
s3[S3LogArchive]
eb[EventBridge]
sns[SNS]
bkp[AWSBackup]
end
mta --> cw
mta --> ssm
mta --> s3
ct --> s3
eb --> sns
cfg --> sns
gd --> sns
insp --> snsWhy Each AWS Service Exists
| Service | Role in KumoMTA Platform | Why It Is Included |
|---|---|---|
| Route53 | Authoritative DNS for sending domains | Required for SPF/DKIM/DMARC/MX/MAIL FROM records |
| ACM | TLS cert lifecycle for HTTPS surfaces | Automates cert management for web/admin endpoints |
| CloudFront | Optional HTTPS acceleration/security for web surfaces | Not for SMTP path; useful for tracking endpoints |
| AWS WAF | HTTP-layer protection for web/admin APIs | Protects non-SMTP endpoints from abuse |
| ALB | HTTPS load balancing for admin/tracking/API | Not SMTP listener replacement |
| EC2 | Runs KumoMTA | Core MTA compute runtime |
| EBS gp3 | Message spool/log disk | Predictable IOPS and throughput tuning |
| EFS | Optional shared policy/templates across nodes | Useful when multiple MTAs share state artifacts |
| VPC | Network boundary control | Segmentation and egress control |
| Security Groups | Stateful allow-listing | SMTP and ops access control |
| IAM Roles | Instance identity | Secure access to S3, CloudWatch, SSM, Secrets |
| KMS | Encryption keys | Encrypts EBS/S3/Secrets data at rest |
| S3 | Durable log and event archive | Retention, audit, Athena analysis |
| CloudWatch | Metrics/logs/alarms | Operational health and SLO monitoring |
| Systems Manager | Patch, command, session management | SSH-less hardened operations |
| CloudTrail | API audit logs | Compliance and forensic traceability |
| EventBridge | Event routing and automation | Alarm/event to workflow routing |
| SNS | Alert fanout | Pager/chat/email integration |
| AWS Backup | Backup policy orchestration | Recovery posture for config/data artifacts |
| AWS Config | Drift/compliance visibility | Control validation and audits |
| GuardDuty | Threat detection | Compromise and anomaly signals |
| Inspector | Vulnerability scanning | Continuous EC2 package exposure visibility |
Infrastructure Design
VPC and Subnet Design
flowchart LR
igw[InternetGateway] --> pub[PublicSubnetA]
igw --> pubb[PublicSubnetB]
pub --> eip[EIPonMTAInstance]
pubb --> nat[NATGateway]
pub --> alb2[ALBHTTPSOnly]
pubb --> bastion[NoBastionUseSSM]
nat --> priv[PrivateSubnetA]
nat --> privb[PrivateSubnetB]
priv --> tools[OpsAutomationAndCollectors]
privb --> analytics[LogProcessing]CIDR and Route Planning Example
| Component | Example CIDR | Notes |
|---|---|---|
| VPC | 10.40.0.0/16 | Leaves room for scaling |
| Public subnet A | 10.40.10.0/24 | EC2 MTA + ALB + NAT |
| Public subnet B | 10.40.11.0/24 | HA infra components |
| Private subnet A | 10.40.20.0/24 | Log processors, tooling |
| Private subnet B | 10.40.21.0/24 | Redundant private workloads |
Security Groups
- Inbound SMTP ports:
25,587, optional465depending client support. - Ops ports: avoid public SSH; use SSM Session Manager.
- Outbound: allow DNS (53), NTP (123), SMTP (25/587), HTTPS (443) for updates/APIs.
NACL Guidance
Use SGs as primary control and keep NACLs simple unless compliance requires strict subnet ACLs. Overly restrictive NACLs are a common source of intermittent SMTP failure under ephemeral port ranges.
Dedicated IP and Reverse DNS Strategy
- Attach stable Elastic IPs to each outbound MTA node.
- Configure PTR records through AWS support process for each EIP.
- Ensure forward-confirmed reverse DNS:
mail1.example.comA->EIP and PTR->same hostname.
Multi-AZ Considerations
For outbound SMTP continuity:
- Run at least two MTA nodes in separate AZs for active-passive or active-active paths.
- Keep queue policy and shaping definitions synchronized.
- Use health-aware sender routing at the application layer.
Server Sizing Guidance
Sizing depends on message size, TLS cost, destination diversity, and queue depth profile.
| Tier | Suggested Instance Class | vCPU | RAM | EBS gp3 Baseline | Estimated Emails/Hour | Estimated Emails/Day | Concurrent SMTP Sessions |
|---|---|---|---|---|---|---|---|
| Small | c7i.xlarge or m7i.xlarge | 4 | 16 GiB | 500 GB, 6k IOPS | 50k-150k | 1M-3M | 200-600 |
| Medium | c7i.2xlarge | 8 | 32 GiB | 1 TB, 10k IOPS | 150k-400k | 3M-10M | 600-1500 |
| Large | c7i.4xlarge | 16 | 64 GiB | 2 TB, 16k IOPS | 400k-1M | 10M-25M | 1500-3500 |
| Enterprise | c7i.8xlarge+ multi-node | 32+ | 128+ GiB | 4 TB+, tuned throughput | 1M+ | 25M+ | 3500+ |
Operating System Selection
| OS | Pros | Cons | Recommendation |
|---|---|---|---|
| Amazon Linux 2023 | Native AWS integration, predictable patching, IAM tooling alignment | Package ecosystem differences vs Ubuntu | Strong default for AWS-first teams |
| Ubuntu LTS | Familiar ops model, broad package docs | Extra hardening consistency needed across teams | Strong if your org standardizes on Ubuntu |
| Rocky Linux | RHEL-like stability, enterprise familiarity | Team may need extra package mapping | Good where RHEL parity is required |
Operationally, choose one OS and standardize every automation path (bootstrap, hardening, patching, CIS controls, and log pipeline).
Step-by-Step Installation (Production-Oriented)
Context: examples assume Amazon Linux 2023 or Rocky 9 style package workflow and systemd-based service management.
1) Prepare Instance and Baseline Packages
sudo dnf update -y
sudo dnf install -y curl wget jq git vim tar unzip policycoreutils-python-utils firewalld chrony
sudo systemctl enable --now chronyd2) Disable Conflicting Local MTA Services
sudo systemctl disable --now postfix || true
sudo systemctl disable --now sendmail || true
sudo ss -lntp | rg ':25|:587|:465'3) Hostname and FQDN Setup
sudo hostnamectl set-hostname mail1.example.com
echo "127.0.0.1 mail1.example.com mail1 localhost" | sudo tee -a /etc/hosts
hostname -f4) Firewall Setup (Host Level)
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-port=25/tcp
sudo firewall-cmd --permanent --add-port=587/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all5) Install KumoMTA from Official Repository
Use KumoMTA official installation instructions for your specific distribution/version.
# Context: Rocky 9 / Amazon Linux 2023 — follow official repo steps for your OS
# https://docs.kumomta.com/userguide/installation/linux/
sudo dnf install -y kumomta kumo-tsa-daemon6) Directory and Permission Baseline
sudo mkdir -p /opt/kumomta/etc/policy
sudo mkdir -p /var/log/kumomta
sudo chown -R root:root /opt/kumomta/etc
sudo chmod -R 750 /opt/kumomta/etc7) TLS Certificate Placement
sudo mkdir -p /etc/pki/kumomta
sudo cp fullchain.pem /etc/pki/kumomta/mail.crt
sudo cp privkey.pem /etc/pki/kumomta/mail.key
sudo chmod 640 /etc/pki/kumomta/mail.key
sudo chgrp kumomta /etc/pki/kumomta/mail.key8) Service Enablement
sudo systemctl daemon-reload
sudo systemctl enable --now kumomta
sudo systemctl enable --now kumo-tsa-daemon
sudo systemctl status kumomta --no-pager
sudo systemctl status kumo-tsa-daemon --no-pager9) First Health Checks
sudo ss -lntp | rg ':25|:587'
sudo journalctl -u kumomta -n 100 --no-pager
openssl s_client -starttls smtp -connect mail1.example.com:587 -servername mail1.example.com10) Auto Recovery and Instance Protection
- Enable EC2 Auto Recovery alarms for system status checks.
- Use EBS snapshots and AMI bake process for repeatable rebuilds.
Configure KumoMTA for Production
Example Policy Skeleton (/opt/kumomta/etc/policy/init.lua)
local kumo = require 'kumo'
kumo.on('init', function()
kumo.set_listener {
listen = '0.0.0.0:25',
hostname = 'mail1.example.com',
relay_hosts = { '10.40.0.0/16' },
}
kumo.set_listener {
listen = '0.0.0.0:587',
hostname = 'mail1.example.com',
tls_certificate = '/etc/pki/kumomta/mail.crt',
tls_private_key = '/etc/pki/kumomta/mail.key',
require_auth = true,
}
end)
kumo.on('get_queue_config', function(domain, tenant, campaign)
if domain:match('gmail%.com$') then
return {
max_age = '72h',
retry_interval = '5m',
max_retry_interval = '1h',
connection_limit = 50,
}
end
return {
max_age = '48h',
retry_interval = '10m',
max_retry_interval = '2h',
connection_limit = 30,
}
end)Egress Path and IP Pool Strategy
- Keep transactional and marketing traffic on separate IP pools.
- Create domain-group-specific routes to avoid reputation coupling.
- Keep a reserve IP pool for incident isolation.
Example Queue Policy Table
| Destination Group | Max Connections | Initial Retry | Max Retry | Notes |
|---|---|---|---|---|
| Gmail/Google Workspace | 50 | 5m | 60m | Conservative ramp during warmup |
| Microsoft domains | 40 | 10m | 90m | Watch temp fail patterns |
| Yahoo/AOL | 30 | 10m | 120m | Strict complaint sensitivity |
| Long-tail domains | 20 | 15m | 180m | Lower priority batch routes |
Bounce and Retry Handling Guidance
- Classify hard bounces immediately as suppression candidates.
- Cap soft-bounce retry windows to avoid stale-delivery harm.
- Separate policy per mailbox provider when practical.
Logging Strategy in Config
- Structured logs with route, domain, queue, and response code fields.
- Avoid high-cardinality fields in CloudWatch metric filters unless necessary.
Lua Policy Examples
Tenant-based IP Pool Selection
kumo.on('select_egress_path', function(msg)
local tenant = msg:meta('tenant') or 'default'
if tenant == 'transactional' then
return 'ip_pool_txn'
end
if tenant == 'marketing' then
return 'ip_pool_mkt'
end
return 'ip_pool_default'
end)Basic Risk Guardrail
kumo.on('smtp_server_message_received', function(msg)
local from = msg:from_header() or ''
if from:match('@example%.invalid$') then
return kumo.reject(550, 'Blocked sender domain policy')
end
return kumo.accept()
end)AWS DNS Configuration for Deliverability
DNS Record Set Blueprint (Route53)
; SPF (TXT)
example.com. 300 IN TXT "v=spf1 ip4:203.0.113.10 ip4:203.0.113.11 include:amazonses.com -all"
; DKIM selector (TXT)
k1._domainkey.example.com. 300 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."
; DMARC
_dmarc.example.com. 300 IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1; adkim=s; aspf=s; pct=100"
; MAIL FROM / Return-Path domain
bounce.example.com. 300 IN MX 10 feedback-smtp.us-east-1.amazonses.com.
bounce.example.com. 300 IN TXT "v=spf1 include:amazonses.com -all"
; MTA host
mail1.example.com. 300 IN A 203.0.113.10SPF Guidance
- Keep SPF under DNS lookup limits.
- Prefer explicit IP entries for self-hosted MTA + minimal includes.
- End with strict fail (
-all) after validation period.
DKIM Guidance
- Use at least 2048-bit keys where provider compatibility allows.
- Rotate selectors on predictable cadence.
DMARC Guidance
- Start with
p=nonefor visibility if domain maturity is low. - Enforce
quarantinethenrejectas alignment confidence increases.
Reverse DNS
Coordinate PTR setup with AWS support for each Elastic IP and keep forward/reverse alignment consistent.
Security Best Practices
IAM and Access
- Use least-privilege instance role with explicit actions for CloudWatch, S3 write, KMS decrypt, and SSM channels.
- Deny wildcard write permissions across unrelated services.
SSH Hardening and SSM
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
AllowTcpForwarding no
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 20sudo systemctl restart sshdPrefer SSM Session Manager and disable internet-exposed SSH where possible.
Fail2Ban (if SSH exposed)
# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 5
findtime = 10m
bantime = 1hSecrets and Key Management
- Store API keys/credentials in Secrets Manager.
- Encrypt secrets, EBS volumes, and S3 buckets with KMS CMKs where required.
Patch and Vulnerability Operations
- Use SSM Patch Manager windows.
- Integrate Inspector findings into ticket workflow.
Audit and Threat Detection
- Organization-level CloudTrail with immutable S3 archive and retention controls.
- GuardDuty alerting to SNS + incident response channel.
- AWS Config rules for drift detection on security groups, IAM, and public exposure.
Monitoring Architecture
flowchart LR
mta2[KumoMTANodes] --> cwa[CloudWatchAgent]
cwa --> cwm[CloudWatchMetrics]
cwa --> cwl[CloudWatchLogs]
cwm --> alarms[CloudWatchAlarms]
alarms --> eb2[EventBridge]
eb2 --> sns2[SNSPagerChat]
cwl --> insights[LogsInsights]
cwl --> s3l[S3Archive]
s3l --> athena[AthenaAnalysis]Priority Metrics
| Domain | Metric | Alert Condition Example |
|---|---|---|
| Queue health | Queue depth | > threshold for 15m |
| Delivery | Success ratio | Drops below SLO window |
| Bounce | Hard bounce rate | Above policy baseline |
| Complaints | Complaint rate | Above mailbox thresholds |
| Latency | Time-to-delivery | p95 exceeds SLA |
| System | CPU, memory, disk, inode | Sustained >80% |
| SMTP | Connect errors, TLS failures | Rapid increase by destination |
CloudWatch Agent Example
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/kumomta/main.log",
"log_group_name": "/email/kumomta/main",
"log_stream_name": "{instance_id}",
"timezone": "UTC"
}
]
}
}
},
"metrics": {
"append_dimensions": {
"InstanceId": "${aws:InstanceId}"
},
"metrics_collected": {
"cpu": { "resources": ["*"], "measurement": ["cpu_usage_idle", "cpu_usage_iowait"] },
"disk": { "resources": ["*"], "measurement": ["used_percent", "inodes_free"] },
"mem": { "measurement": ["mem_used_percent"] },
"netstat": { "measurement": ["tcp_established", "tcp_time_wait"] }
}
}
}Alarm Example (Queue Growth)
Resources:
QueueDepthAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: kumomta-queue-depth-high
Namespace: Custom/KumoMTA
MetricName: QueueDepth
Statistic: Average
Period: 60
EvaluationPeriods: 15
Threshold: 50000
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- arn:aws:sns:us-east-1:123456789012:email-ops-alertsLogging and Analytics Pipeline
flowchart TD
logs[KumoMTALogs] --> cwl2[CloudWatchLogs]
cwl2 --> sub[SubscriptionFilter]
sub --> kdf[Firehose]
kdf --> s3raw[S3RawBucket]
s3raw --> glue[GlueCatalog]
glue --> ath[Athena]
s3raw --> os[OpenSearchOptional]Log Retention and Rotation
# /etc/logrotate.d/kumomta
/var/log/kumomta/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 root kumomta
postrotate
systemctl kill -s HUP kumomta >/dev/null 2>&1 || true
endscript
}Retention Policy Guidance
- Hot logs in CloudWatch: 14-30 days.
- Warm archive in S3: 90-365 days depending compliance.
- Cold legal hold tiering as needed.
Email Deliverability Operations
flowchart LR
prep[DomainAndIPPreparation] --> auth[SPFDKIMDMARC]
auth --> warmup[DedicatedIPWarmup]
warmup --> policy2[MailboxProviderShaping]
policy2 --> feedback[FeedbackLoopAndSuppression]
feedback --> optimize[ContentAndListHygieneOptimization]
optimize --> reputation[StableSenderReputation]Dedicated IP Warmup
- Start with low daily volume and gradual ramp.
- Keep complaint and hard-bounce rates tightly monitored.
- Avoid mixing transactional and promotional streams early.
Domain Warmup
- Begin with highly engaged recipients.
- Stagger sends by provider and user engagement score.
Authentication Stack
- SPF, DKIM, DMARC are foundational.
- Add BIMI only after DMARC enforcement maturity.
- Implement MTA-STS and TLS-RPT for transport trust and reporting.
Feedback and Reputation Inputs
- Process FBL data where available.
- Track Google Postmaster metrics.
- Review Microsoft SNDS, Yahoo complaint feedback channels, and Cisco Talos reputation signals.
Content and Protocol Hygiene
- Stable HELO/EHLO identity aligned with PTR and cert CN/SAN.
- Valid List-Unsubscribe for bulk streams.
- Suppression list discipline for hard bounces and complainers.
High Availability Patterns
flowchart TD
app2[SendingApps] --> route[TrafficRouter]
route --> mtaA[KumoMTAAZA]
route --> mtaB[KumoMTAAZB]
mtaA --> mxA[RecipientMX]
mtaB --> mxB[RecipientMX]
mtaA --> s3cfg[S3PolicyArtifacts]
mtaB --> s3cfg
s3cfg --> dr[DRRestorePath]Pattern Trade-offs
| Pattern | Pros | Cons | Use When |
|---|---|---|---|
| Single server | Lowest complexity | Single point of failure | Low-risk early stage |
| Active-passive | Better resilience | Failover orchestration needed | Moderate volume with strict uptime goals |
| Active-active | Highest throughput and resilience | More complex queue and policy synchronization | High-volume enterprise |
DR Baseline
- Immutable config snapshots in S3 versioned bucket.
- AMI images for fast rebuild.
- Recovery runbooks tested quarterly.
Performance Tuning
Kernel and Sysctl Baseline
# /etc/sysctl.d/99-kumomta.conf
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.core.netdev_max_backlog = 16384
fs.file-max = 2097152
vm.swappiness = 10sudo sysctl --systemFile Descriptor and Limits
# /etc/security/limits.d/kumomta.conf
kumomta soft nofile 262144
kumomta hard nofile 262144
kumomta soft nproc 65535
kumomta hard nproc 65535EBS Tuning Notes
- Prefer gp3 with explicit IOPS/throughput targets instead of defaults.
- Keep queue and log disks separated where sustained heavy writes are expected.
SMTP Concurrency Tuning
- Increase per-destination concurrency only with observed acceptance stability.
- Couple concurrency changes with complaint/bounce monitoring windows.
Cost Optimization
Estimated monthly costs vary heavily by egress volume, instance family, and retention profile.
| Profile | Compute | Storage | Data Transfer | Observability | Security/Compliance | Approx Monthly Total |
|---|---|---|---|---|---|---|
| Development | $120-$300 | $30-$80 | $20-$100 | $20-$80 | $10-$50 | $200-$610 |
| Startup Production | $400-$1,200 | $100-$300 | $200-$900 | $150-$500 | $80-$250 | $930-$3,150 |
| Medium Scale | $1,500-$4,000 | $300-$900 | $1,000-$4,500 | $500-$1,800 | $250-$900 | $3,550-$12,100 |
| Enterprise Scale | $6,000+ | $1,200+ | $5,000+ | $2,500+ | $1,200+ | $15,900+ |
Savings Opportunities
- Use Graviton-compatible components where validated.
- Apply log sampling/aggregation to reduce ingest costs.
- Use S3 lifecycle tiers for long retention.
- Tune over-provisioned gp3 IOPS after baseline period.
Troubleshooting Playbook
Common Incident Patterns
| Issue | Likely Cause | Fast Checks | Remediation |
|---|---|---|---|
| DNS auth failures | SPF/DKIM/DMARC misconfig | dig txt, DMARC validators | Correct records, reduce TTL during changes |
| TLS handshake errors | Cert mismatch or stale chain | openssl s_client | Replace cert chain, verify hostname alignment |
| SMTP timeouts | Port 25 block or SG/NACL | VPC flow logs, nc -vz | AWS port 25 request, SG fix, route fix |
| Connection refused | Service down or firewall block | systemctl, ss -lntp | Restart service, fix listen config |
| Queue stuck growth | Provider throttling/policy mismatch | Queue depth by domain | Reduce concurrency, adjust retry profile |
| Blacklisting | Reputation event | Blocklist checks/postmaster dashboards | Pause affected streams, warmup again |
| SES hybrid relay failures | IAM/credential/policy drift | CloudTrail + app logs | Rotate secrets, validate relay endpoint |
| CloudWatch gap | Agent failure | systemctl status amazon-cloudwatch-agent | restart + config validation |
| Reverse DNS mismatch | PTR/A mismatch | dig -x, dig A | Correct forward/reverse alignment |
| High spam placement | Engagement/content/list hygiene issues | Postmaster metrics | tighten list quality + cadence + segmentation |
| High complaint rate | Frequency mismatch/audience fit | complaint stream metrics | throttle, re-segment, suppress complainers |
SMTP Flow Diagram for Debugging
sequenceDiagram
participant App as SenderApp
participant MTA as KumoMTA
participant MX as RecipientMX
App->>MTA: Submit message (SMTP/API)
MTA->>MTA: Queue and policy evaluation
MTA->>MX: Connect + STARTTLS + SMTP commands
MX-->>MTA: 2xx/4xx/5xx response
MTA-->>App: Event status webhook/logMaintenance and Operations Cadence
| Cadence | Activities |
|---|---|
| Daily | Queue health checks, bounce/complaint watch, alarm review |
| Weekly | Policy tweaks, suppression audits, cert and key checks |
| Monthly | Patch cycles, cost review, warmup progression review |
| Quarterly | DR drills, security control validation, architecture review |
Certificate Renewal Workflow
- Track expiration in CloudWatch/EventBridge.
- Renew with overlap and staged rollout.
- Validate with STARTTLS probes before full traffic cutover.
Disaster Recovery Drill Requirements
- Rebuild node from AMI + config artifacts.
- Restore secrets and policy.
- Verify delivery path, auth, and observability in test domain.
Do’s and Don’ts (Production Operations)
Do’s (30)
| # | Do | Why |
|---|---|---|
| 1 | Separate transactional and marketing IP pools | Limits blast radius |
| 2 | Enforce SPF, DKIM, DMARC before scaling | Foundation for trust |
| 3 | Use dedicated hostnames per sending node | Better traceability |
| 4 | Align PTR and HELO identities | Reduces trust failures |
| 5 | Start with conservative concurrency | Prevents early throttling |
| 6 | Warm IPs gradually | Protects reputation buildup |
| 7 | Store policies as code in version control | Auditable changes |
| 8 | Keep immutable config backups | Fast rollback |
| 9 | Use SSM over public SSH | Reduces attack surface |
| 10 | Enable CloudTrail org-wide | Forensic coverage |
| 11 | Alert on queue depth growth | Early congestion signal |
| 12 | Alert on complaint spikes | Reputation protection |
| 13 | Tune retries by mailbox provider | Better acceptance outcomes |
| 14 | Maintain suppression lists | Avoid repeat hard bounces |
| 15 | Use TLS everywhere possible | Transport security |
| 16 | Rotate keys and certs | Limits key exposure risk |
| 17 | Patch on a fixed cadence | Vulnerability reduction |
| 18 | Tag resources by environment/owner | Cost and ops clarity |
| 19 | Use separate domains/subdomains by stream | Isolation and control |
| 20 | Validate DNS after every change | Prevents silent breakage |
| 21 | Capture structured logs | Better troubleshooting |
| 22 | Use Athena for historical analysis | Cost-efficient insights |
| 23 | Test failover quarterly | Real DR confidence |
| 24 | Document every runbook | Lower MTTR |
| 25 | Keep a reserve IP pool | Incident containment |
| 26 | Gate high-risk config changes | Avoid accidental outages |
| 27 | Baseline performance before tuning | Avoid random tuning |
| 28 | Use explicit IAM permissions | Least privilege |
| 29 | Review cloud spend monthly | Cost governance |
| 30 | Measure deliverability per destination | Actionable operations |
Don’ts (30)
| # | Don’t | Why |
|---|---|---|
| 1 | Don’t put SMTP behind CloudFront/WAF/ALB | Wrong protocol path |
| 2 | Don’t share one IP pool for all traffic | Reputation coupling |
| 3 | Don’t skip reverse DNS | Trust and acceptance impact |
| 4 | Don’t open SSH to the world | Security risk |
| 5 | Don’t run without alarms | Blind failure risk |
| 6 | Don’t ignore soft-bounce trends | Early degradation signal |
| 7 | Don’t ramp volume abruptly | Warmup shock |
| 8 | Don’t leave DMARC at none forever | Weak spoofing posture |
| 9 | Don’t hardcode secrets in config files | Credential leakage |
| 10 | Don’t run unversioned policy changes | No rollback trail |
| 11 | Don’t keep unlimited log retention | Cost explosion |
| 12 | Don’t treat all domains equally | Provider behavior differs |
| 13 | Don’t mix prod and test domains | Reputation contamination |
| 14 | Don’t over-tighten NACLs blindly | Intermittent network failures |
| 15 | Don’t skip disk inode monitoring | Hidden write outages |
| 16 | Don’t ignore complaint loops | Reputation collapse |
| 17 | Don’t delay patching critical CVEs | Elevated exposure |
| 18 | Don’t disable TLS verification casually | Security downgrade |
| 19 | Don’t run DR plans only on paper | False confidence |
| 20 | Don’t use wildcard IAM roles | Privilege sprawl |
| 21 | Don’t change SPF includes without testing | Auth breakage |
| 22 | Don’t leave old DKIM selectors active forever | Key hygiene failure |
| 23 | Don’t skip post-change synthetic tests | Late outage discovery |
| 24 | Don’t use one queue policy for all providers | Poor acceptance tuning |
| 25 | Don’t flood retries aggressively | Deferral storm |
| 26 | Don’t suppress observability data in incidents | Slower triage |
| 27 | Don’t run with default sysctl at scale | Throughput bottlenecks |
| 28 | Don’t scale compute before fixing policy | Wasteful spend |
| 29 | Don’t assume SES fallback always healthy | Hidden dependency risk |
| 30 | Don’t ignore sender-content quality signals | Inbox placement decline |
Common Real-World Mistakes (25)
| # | Problem | Impact | Solution |
|---|---|---|---|
| 1 | PTR not configured before go-live | High rejection rates | Complete DNS identity set before traffic |
| 2 | Marketing on transactional IP | OTP/reset placement degradation | Split by stream and pool |
| 3 | Missing suppression workflow | Repeated hard bounces | Auto-suppress with expiry policy |
| 4 | One-size retries | Queue bloat and delay | Destination-aware retry matrix |
| 5 | No complaint threshold alarms | Silent reputation collapse | Hard alert thresholds |
| 6 | Public SSH enabled broadly | Compromise risk | SSM-first operations |
| 7 | Cert CN mismatch | STARTTLS trust failures | Align cert names with SMTP hostnames |
| 8 | Overly broad SG egress | Policy non-compliance | Restrict egress by need |
| 9 | Untested backup restore | Slow recovery | Monthly restore validation |
| 10 | Log retention set to never expire | Excess costs | Tiered retention strategy |
| 11 | No queue decomposition by tenant | Noisy-neighbor outages | Tenant-aware queue design |
| 12 | Changing SPF and DKIM together in peak window | Hard-to-debug auth issues | Stagger auth changes |
| 13 | Missing synthetic SMTP probe | Late outage detection | Scheduled probe checks |
| 14 | No warmup plan for new IPs | Temporary blocking | Enforced warmup schedule |
| 15 | Ignoring provider-specific 4xx patterns | Repeated throttling | Provider-tailored shaping |
| 16 | Ad hoc config edits on hosts | Drift and audit gaps | GitOps-style policy deployment |
| 17 | Not tracking inbox by provider | Blind optimization | Segment metrics by mailbox family |
| 18 | IAM role reused across environments | Blast radius increase | Environment-specific roles |
| 19 | Scaling instance size before fixing queue logic | Higher cost, same failures | Optimize policy first |
| 20 | Missing max queue age caps | Stale deliveries | Cap age by message type |
| 21 | Incomplete DMARC reporting mailbox ops | Lost insight | Monitor aggregate/forensic feed health |
| 22 | No separation of bulk send windows | Complaint spikes | Spread campaign cadence |
| 23 | No runbook for blacklist events | Long MTTR | Prebuilt delist and throttle runbook |
| 24 | Trusting a single observability sink | Monitoring blind spot | CW + S3 archive + alert fanout |
| 25 | Treating deliverability as one-time setup | Slow decay over months | Weekly deliverability review cycle |
Production Readiness Checklist (100+)
Infrastructure
- VPC CIDR documented and approved
- Public and private subnets defined
- Route tables validated for SMTP and ops paths
- Internet Gateway attached and tested
- NAT requirements explicitly documented
- EBS encryption enabled by default
- gp3 IOPS/throughput sized for queue workload
- Instance profile attached and validated
- Immutable AMI build pipeline documented
- Auto recovery alarms configured
Security
- Root login disabled
- Password SSH auth disabled
- SSM Session Manager validated
- SSH source ranges restricted if enabled
- Fail2Ban configured where applicable
- Host firewall policy deployed
- CIS baseline hardening reviewed
- Secrets in Secrets Manager only
- KMS key policies reviewed
- Security Hub findings integrated into workflow
Networking
- SMTP ports required are open in SG
- Unused inbound ports blocked
- NACL rules validated for ephemeral ranges
- DNS resolver access confirmed
- NTP synchronization verified
- VPC flow logs enabled
- EIP allocation and mapping documented
- Reverse DNS request submitted for each EIP
- HELO hostnames mapped to valid A records
- IPv6 posture documented (enabled/disabled)
DNS and Authentication
- SPF record published and validated
- SPF lookup count within limits
- DKIM selectors published
- DKIM signing validated on live message
- DMARC record published
- DMARC rua/ruf mailbox operational
- MAIL FROM/bounce domain configured
- MX records validated where needed
- DNS TTL strategy documented for cutover
- BIMI readiness assessed
SMTP and MTA
- KumoMTA service starts on boot
- Listener ports verified
- Submission auth policy tested
- Queue age limits configured
- Retry policies destination-aware
- Connection limits destination-aware
- Dedicated IP pool mapping complete
- Transactional and marketing streams isolated
- Suppression logic implemented
- Dead-letter or quarantine process defined
Deliverability
- IP warmup schedule documented
- Domain warmup schedule documented
- Complaint threshold defined per provider
- Hard bounce threshold defined
- Content lint/check process defined
- List hygiene workflow documented
- List-Unsubscribe headers configured for bulk
- Google Postmaster access verified
- Microsoft SNDS access verified
- Sender reputation dashboards reviewed weekly
Monitoring and Alerting
- CloudWatch agent deployed
- Queue depth metrics emitting
- SMTP error metrics emitting
- Delivery latency tracked
- Bounce and complaint metrics tracked
- CPU/memory/disk/inode alarms in place
- Alarm routing to SNS validated
- On-call escalation policy documented
- Synthetic SMTP checks scheduled
- Incident dashboard created
Logging and Analytics
- Structured log format enabled
- CloudWatch log groups with retention set
- Log shipping to S3 validated
- S3 lifecycle policies configured
- Glue catalog for log data created
- Athena query templates prepared
- Sensitive fields redaction policy defined
- Log integrity controls documented
- OpenSearch ingestion path assessed (if needed)
- Cost guardrails for log volume configured
Scaling and HA
- Capacity model documented by traffic class
- Active-passive or active-active strategy chosen
- Multi-AZ deployment tested
- Policy sync mechanism validated
- Node replacement runbook tested
- Failover trigger conditions defined
- Traffic router failover behavior tested
- Reserve IP pool available
- SES fallback path tested if used
- Performance baseline captured before scale-out
Backup and DR
- Config backups versioned in S3
- Secrets backup strategy documented
- AMI snapshot cadence defined
- Restore test completed in non-prod
- RTO target approved
- RPO target approved
- DR communication plan documented
- DR tabletop exercise completed
- Cross-region backup requirements reviewed
- Quarterly DR drill scheduled
Compliance and Audit
- CloudTrail enabled and centralized
- Config rules for key controls enabled
- GuardDuty enabled in all accounts/regions
- Inspector scans active for instances
- Retention meets policy requirements
- Access reviews scheduled
- Change approvals auditable
- Data classification for logs documented
- Encryption at rest and in transit verified
- Exception register maintained
Operations and Maintenance
- Patch schedule approved
- Maintenance windows documented
- Certificate renewal process tested
- Runbooks updated after incidents
- Capacity review monthly
- Cost review monthly
- Deliverability review weekly
- Queue policy review biweekly
- Incident postmortem template in use
- Ownership matrix current
DNS Flow Diagram
flowchart TD
send[SenderDomainConfig] --> r53z[Route53HostedZone]
r53z --> spfrec[SPFRecord]
r53z --> dkimrec[DKIMSelectors]
r53z --> dmarcrec[DMARCPolicy]
r53z --> arec[ARecordSMTPHost]
arec --> ptr[PTRReverseDNS]
ptr --> trust[MailboxProviderTrustSignals]Queue Processing Diagram
flowchart LR
ingest[MessageIngress] --> classify[ClassifyTenantAndDomain]
classify --> qp[QueuePartition]
qp --> rate[RateAndConcurrencyPolicy]
rate --> attempt[DeliveryAttempt]
attempt -->|2xx| done[Delivered]
attempt -->|4xx| retryq[RetryQueue]
retryq --> rate
attempt -->|5xx| fail[HardFailureSuppression]Disaster Recovery Flow Diagram
flowchart LR
incident[RegionalOrNodeFailure] --> trigger[FailoverTrigger]
trigger --> routeupdate[TrafficReroute]
routeupdate --> standby[StandbyMTAorSecondaryAZ]
standby --> restorecfg[RestorePoliciesSecrets]
restorecfg --> validate[SMTPAndDeliverabilityValidation]
validate --> resume[ResumeProductionTraffic]Code and Configuration Examples Collection
Systemd Service Override
# /etc/systemd/system/kumomta.service.d/override.conf
[Service]
LimitNOFILE=262144
Restart=always
RestartSec=5sudo systemctl daemon-reload
sudo systemctl restart kumomtaSecurity Group Rule Set (Conceptual)
Inbound:
- tcp/25 from trusted senders or internet (if required)
- tcp/587 from app network ranges
- tcp/443 from admin/tracking clients
- tcp/22 from none (SSM preferred)
Outbound:
- tcp/25 to internet recipient MX
- tcp/443 to AWS APIs and package repos
- udp/53 to resolver
- udp/123 to NTPTLS Configuration Baseline
# Conceptual TLS policy for SMTP listeners
min_tls_version = "TLSv1.2"
prefer_server_ciphers = true
cipher_suites = [
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_CHACHA20_POLY1305_SHA256"
]iptables-style Example (if firewalld not used)
sudo iptables -A INPUT -p tcp --dport 25 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 587 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -P INPUT DROPWhat to Do This Week
- Finalize domain and IP identity design (A/PTR/HELO, SPF, DKIM, DMARC).
- Stand up one hardened KumoMTA node in AWS with observability from day one.
- Implement queue segmentation for transactional vs marketing streams.
- Enable destination-aware shaping and conservative warmup policy.
- Configure alarms for queue growth, complaint spikes, and SMTP/TLS failure trends.
- Test restore and failover procedures before increasing daily send volume.
Final Recommendations and Decision Guidance
When KumoMTA Is the Right Choice
- You need fine-grained policy control and multi-stream reputation isolation.
- Your platform has enough engineering maturity to run a persistent email operations program.
- You want to integrate MTA behavior into AWS-native security and observability controls.
When Another MTA or Managed ESP May Be Better
- You do not have internal ownership for ongoing deliverability operations.
- You need turnkey campaign workflows and managed compliance tooling more than routing control.
- Your current send volume does not justify dedicated infrastructure operations.
Enterprise Recommendation
Treat KumoMTA as an operations platform, not just an SMTP service. The infrastructure itself is straightforward; the durable advantage comes from disciplined policy tuning, reputation management, and continuous observability.
What This Post Doesn’t Cover
- Vendor-specific contractual deliverability guarantees.
- A published first-party benchmark dataset for your exact sending profile.
- Region-specific legal counsel for every jurisdiction.
For hybrid or migration paths, see our Amazon SES consulting and SES migration service. Teams evaluating managed ESP alternatives should read How to Migrate from SendGrid to Amazon SES.
FactualMinds Expert Recommendations
FactualMinds is an AWS Select Tier Consulting Partner with deep email infrastructure experience — including migrations from SendGrid, Mailgun, Postmark, and SparkPost to Amazon SES at enterprise scale (case study).
| Scenario | Recommendation |
|---|---|
| Self-hosted MTA with AWS-native ops | KumoMTA on EC2 with policy-as-code, split IP pools, and CloudWatch-first observability |
| Managed deliverability with lower ops burden | Amazon SES with configuration sets and tenant isolation |
| Migrating from ESP to AWS | SES migration service — phased cutover with warmup discipline |
| Hybrid during transition | KumoMTA primary + SES relay for specific streams until reputation stabilizes |
AWS Cloud Architect & AI Expert
AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.



