Architecture
Mailez uses a modular architecture that cleanly separates the control plane from the mail engine.
High-Level Architecture
┌─────────────────────────────────────────────────────────┐
│ Frontend Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Webmail │ │ Admin │ │ mailezine │ │
│ │ (Next.js) │ │ (Next.js) │ │ (single bin) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Backend API (Go+Fiber) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ REST API │ │ Auth │ │ Directory │ │
│ │ (Fiber) │ │ (JWT/RBAC) │ │ Contract │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Archive │ │ DLP │ │ LDAP / SSO │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Mail Engine Layer │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Engine-Agnostic Directory Contract │ │
│ │ (/stack/directory/*) │ │
│ │ ┌────────────────────────────────────────────┐ │ │
│ │ │ mailezine │ │ │
│ │ │ (Single Go binary, all tiers) │ │ │
│ │ └────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Supporting Services │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Rspamd │ │ Unbound │ │ Redis │ │
│ │ (Spam Filter)│ │ (DNS/DoH) │ │ (Cache) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌────────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ SQLite/MySQL/PG│ │ TiDB │ │ MinIO/S3 │ │
│ │ (control DB) │ │ (engine KV) │ │ (msg blobs) │ │
│ └────────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
Core Components
Control Plane (Backend)
- Stack: Go + Fiber + GORM + Redis
- Responsibilities:
- REST API service
- User authentication and authorization (JWT + RBAC)
- Directory contract management (domains, mailboxes, aliases, distribution groups)
- AD/LDAP directory integration and SSO
- Mail archive (capture / retention / review / export)
- Outbound DLP rules and approval flow
- Announcements, audit log, webhook callbacks
- Integration interface with the mail engine
Frontend Applications
- Webmail: Next.js + Tailwind / Base UI + TipTap rich text, for end users
- Admin Console: Next.js + Tailwind / Base UI, for administrators
- Highlights:
- Responsive design
- Internationalization (i18n)
- PWA offline support
- Mobile sync: Exchange ActiveSync / CardDAV / CalDAV
Mail Engine
Mailezine (the only engine, every tier)
- Single binary; all protocols in-house (SMTP / IMAP / POP3 / ManageSieve)
- Pluggable storage: Pebble (single node, dev/community) / TiDB (distributed, enterprise) + MinIO/S3 blob
- Embedded FTS (bleve) + Tika attachment text extraction; converges per node via change-log tailing under multi-active
- Two clustering shapes (enterprise): active-passive lease failover, or the
multitier's fully multi-active engine — every replica serves every account, deliveries are claimed per message and taken over on crash; implicit TLS (465/993/995) mailezine migratemoves traditional Postfix+Dovecot (Maildir) deployments into the KV store- Native support on Linux / macOS / Windows
- Shared infrastructure components (enterprise high-tier): Rspamd (advanced anti-spam), Unbound (DNS/DoH), nginx (HTTP/ACME gateway); the community edition ships built-in baseline anti-spam (authentication results scoring + DNSBL + sender lists + optional greylisting) without them
Directory Contract
An engine-agnostic interface spec defined under /stack/directory/*:
- Domain management
- Mailbox accounts
- Alias configuration
- Distribution groups
- DKIM keys
- Relay settings
Any mail engine that conforms to the contract can be plugged into the system.
Data Flows
Inbound Mail
External SMTP → Engine:25 → built-in baseline anti-spam (community)
↘ Rspamd high-tier (enterprise) → Engine (store)
↓
Archive (capture) → IMAP/POP3/EAS access
Relation to the traditional stack: Rspamd, which used to be a component you
install, wire and tune yourself, is no longer required in the community
deployment. The engine's built-in internal/junk baseline scores the
verifier's authentication results (SPF/DKIM/DMARC), DNSBL hits and sender
lists conservatively — above-threshold mail gets X-Spam headers and is left
to the user's Sieve spamtest rules, and only hard signals (deny-listed
senders, multiple DNSBL hits, stacked DMARC p=reject failures) reject at the
MTA. The enterprise edition switches to the rspamd high-tier client
(statistical learning, fuzzy hashing, phishing detection) by configuring
MAILEZINE_RSPAMD_URL.
Outbound Mail
Webmail/Admin → Backend API → Engine (queue, DKIM-signed at enqueue) → DLP (scan/approve, enterprise) → External SMTP
Administrative Operations
Admin Console → Backend API → directory contract → Engine (config update)
Deployment Architectures
Single-Node (development / small scale)
┌─────────────────────────────────────┐
│ Docker Compose │
│ ┌─────────┐ ┌─────────┐ │
│ │ Backend │ │ Webmail │ │
│ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Admin │ │ Engine │ │
│ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Rspamd │ │ Redis │ │
│ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────────────┐ │
│ │ SQLite │ │ Pebble + FS │ │
│ └─────────┘ └─────────────────┘ │
└─────────────────────────────────────┘
Distributed (production / large scale)
┌──────────────┐ ┌──────────────┐
│ Backend │ │ Backend │ (multi-instance + load balancing)
└──────────────┘ └──────────────┘
│ │
└────────┬───────┘
▼
┌──────────────┐
│ Redis │ (shared state)
└──────────────┘
│
▼
┌──────────────┐
│ MySQL + TiDB │ (shared control DB / engine KV)
└──────┬───────┘
│
┌──────┴──────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Engine 1 │ │ Engine 2 │ (HA lease + MinIO/S3 blob)
└──────────────┘ └──────────────┘
Security Design
Transport Security
- MTA-STS — enforce TLS in transit
- DANE — DNS-based certificate validation
- DKIM — outbound mail signing
- DMARC — anti-spoofing policy
Authentication Security
- JWT — stateless tokens
- Two-factor authentication — TOTP support
- RBAC — role-based access control
- App tokens — dedicated passwords for third-party apps
- Login rate limiting — brute-force protection
Data Security
- PGP — end-to-end encryption
- S/MIME — certificate signing and CMS encryption
- Remote image blocking — prevents tracking
- Attachment scanning — malware detection
- Audit log — action tracking
- Archive + DLP approval — compliance retention and outbound control
Extensibility
Horizontal Scaling
- Backend API is stateless and can be deployed across instances (
mailezctl up ha; the gateway re-resolves replicas dynamically, no sticky sessions) - Scheduled sends are atomically claimed — concurrent replicas never double-deliver, and a dead replica's claim is reclaimed automatically
- Background workers elect a single leader through a DB lease; if the leader dies another replica takes over within 60 seconds
- Large attachments and the drive live in MinIO/S3, so uploads and downloads can land on different replicas
- Redis supports cluster mode
- Engine storage runs on TiDB KV + MinIO/S3, so instances scale horizontally
- Multi-instance HA lease takes over automatically
Vertical Scaling
- Pluggable storage backends: Pebble (single node) / TiDB (distributed)
- Database connection pooling
- Cache tuning
Plugin Extensibility
- Pluggable mail engines
- Pluggable storage backends
- Extensible auth backends
Monitoring & Operations
Health Checks
- Backend API:
/health - Mail engine: engine-specific endpoint
- Dependencies: Redis, Rspamd
Logging
- Structured logs (JSON)
- Configurable log levels
- Centralized log collection (optional)
Metrics
- Health endpoints and structured logs (JSON)
- Runtime metrics such as queue depth, latency and throughput
- Performance benchmarks in the Mailezine repo
docs/benchmark-results.md
Technical Decisions
See each component's decision documents: