How I Built Email Butler: Architecture of a 5M/Month Email Platform
A deep dive into the technical architecture behind Email Butler — from queue design to retry logic, analytics, and real-time monitoring.
Email Butler processes over 5 million emails per month with a 99.2% inbox placement rate. Here is how the architecture makes that possible.
Queue-First Design
Every outgoing email lands in a Redis-backed priority queue. We use BullMQ for job scheduling, which gives us delayed jobs, retries with exponential backoff, and rate limiting out of the box. Each tenant gets its own queue to prevent noisy neighbors from affecting others.
Template Engine & Personalization
Templates are stored in PostgreSQL as JSON schemas with Handlebars syntax. At send time, the worker merges user data and caches the compiled template in Redis for 5 minutes. This keeps our PostgreSQL read load minimal even during bulk campaigns.
Real-Time Analytics Pipeline
Delivery events (sent, delivered, bounced, opened, clicked) are streamed through WebSockets to a Next.js dashboard. Event data is first written to Redis Streams, then aggregated into time-series buckets in InfluxDB. Grafana renders the dashboards, and alerts fire via Slack when delivery rates drop below 98%.
Retry & Dead Letter Logic
Transient failures (4xx SMTP codes) trigger up to 5 retries with exponential backoff: 1 minute, 5 minutes, 15 minutes, 1 hour, 4 hours. Permanent failures (5xx) go straight to the dead-letter queue where engineers can inspect headers and diagnose the root cause.
The result is a system that scales horizontally, recovers gracefully from failures, and gives operators full visibility into every message.
Written by Irfan Naseem
Senior Software Engineer at Netcode. Building email infrastructure and scalable systems.