Saturday, August 8, 2026

Build a Temporary Email Service Backend on a Budget Step by Step

Disposable email addresses process over 100 million temporary inboxes daily across major providers like Guerrilla Mail and 10 Minute Mail, according to industry estimates. Developers building SaaS tools, testing email workflows, or protecting user privacy often need a custom temporary email backend but face steep costs from managed services like Mailgun or SendGrid, which charge $0.80–$1.50 per 1,000 emails plus infrastructure fees. This guide shows how to deploy a production-ready temporary email service using open-source components — Postfix for SMTP, Dovecot for IMAP/POP3, and a lightweight database — on a $5/month VPS. You'll learn the exact architecture, configuration steps, security hardening, and scaling triggers used by teams at startups like Temp-Mail.io (acquired 2021) and developers at GitHub for CI/CD email testing.

Quick Answer: Deploy Postfix (MTA) + Dovecot (MDA) on a $5/month Ubuntu 22.04 VPS with SQLite for address storage, automate inbox creation via a Python API, enforce 10-minute TTL with cron cleanup, and secure with SPF/DKIM/DMARC — total cost under $60/year versus $500+ for managed APIs.

Why Build Your Own Temporary Email Backend

Cost Control and Data Sovereignty

Managed email APIs charge per thousand emails and meter API calls. A custom backend on a $5 DigitalOcean droplet handles 50,000 daily temporary inboxes for flat-rate hosting. You own all data — critical for GDPR compliance when processing EU user emails. No vendor lock-in: migrate anytime by rsyncing /var/mail and your database.

Full Control Over Retention and Features

Need 5-minute inboxes for OTP testing? 24-hour for trial signups? Custom logic like auto-reply to specific domains? Hard-coded SaaS limits prevent this. Self-hosted lets you implement per-project TTL, webhook callbacks on mail receipt, and attachment stripping — features Mailinator charges enterprise tiers for.

Security and Abuse Mitigation

Public disposable email services get blocklisted fast. Your private backend uses dedicated IPs, custom rate limits (e.g., 20 inboxes/hour/IP), and integrated spamassassin scoring. In 2023, Spamhaus listed 12% of shared disposable email IPs — private instances avoid this collateral damage.

Core Architecture: MTA, MDA, and Storage Layer

Postfix as Mail Transfer Agent (MTA)

Postfix, first released December 1998 by Wietse Venema at IBM Research, handles SMTP receipt and delivery. Its modular daemon architecture — smtpd for incoming, qmgr for queue, smtp for outgoing — isolates failures. Configure virtual_alias_maps to route *@temp.yourdomain.com to a catchall mailbox, then pipe to a Python script that parses recipient, creates inbox if missing, and stores raw MIME.

Dovecot for IMAP/POP3 Access

Dovecot serves stored emails to users via IMAP. Its Maildir format stores each message as a file, enabling atomic operations and easy backup. Enable LMTP (Local Mail Transfer Protocol) for Postfix-to-Dovecot handoff — faster than pipe, supports quota enforcement. Set mail_location = maildir:/var/mail/vhosts/%d/%n with per-user quotas (default 10MB) to prevent disk exhaustion.

Lightweight Storage: SQLite + Redis

SQLite tracks inbox metadata: address, created_at, expires_at, message_count. Zero config, survives reboots, handles 100K rows easily. Redis caches active inboxes for O(1) lookup during SMTP RCPT TO checks — 10x faster than SQL. Example schema: CREATE TABLE inboxes (address TEXT PRIMARY KEY, created INTEGER, expires INTEGER, messages INTEGER DEFAULT 0);

Step-by-Step Deployment on Ubuntu 22.04

Provision and Harden the VPS

  1. Create $5/month droplet (1 vCPU, 1GB RAM, 25GB SSD) at DigitalOcean, Linode, or Vultr. Choose Ubuntu 22.04 LTS.
  2. SSH in, run: apt update && apt upgrade -y && apt install -y ufw fail2ban postfix dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd sqlite3 redis-server python3-pip.
  3. UFW rules: ufw allow 22/tcp && ufw allow 25/tcp && ufw allow 143/tcp && ufw allow 993/tcp && ufw allow 587/tcp && ufw enable.
  4. Fail2ban: copy /etc/fail2ban/jail.conf to jail.local, enable postfix, dovecot, sshd jails with maxretry=3, bantime=3600.

Configure Postfix for Catchall Routing

  1. main.cf: set myhostname = mail.temp.yourdomain.com, mydomain = temp.yourdomain.com, myorigin = $mydomain.
  2. virtual_alias_domains = temp.yourdomain.com
  3. virtual_alias_maps = pcre:/etc/postfix/virtual_alias.pcre
  4. Create /etc/postfix/virtual_alias.pcre with: /^(.+)@temp\.yourdomain\.com$/ catchall@temp.yourdomain.com
  5. Run postmap /etc/postfix/virtual_alias.pcre && systemctl reload postfix.

Set Up Dovecot LMTP and Maildir

  1. 10-mail.conf: mail_location = maildir:/var/mail/vhosts/%d/%n
  2. 10-master.conf: enable lmtp unix listener at /var/spool/postfix/private/dovecot-lmtp with mode=0600, user=postfix, group=postfix.
  3. 10-auth.conf: disable plaintext auth unless SSL, add passdb/userdb for static user 'catchall' with home=/var/mail/vhosts/temp.yourdomain.com/catchall.
  4. mkdir -p /var/mail/vhosts/temp.yourdomain.com/catchall && chown -R vmail:vmail /var/mail/vhosts.

Application Logic: Inbox API and Cleanup

Python Flask API for Inbox Management

Create /app/api.py with endpoints: POST /inbox creates random address (uuid4()[:8]@temp.yourdomain.com), inserts into SQLite with expires_at = now + 600 (10 min), returns address and websocket token. GET /inbox/

/messages polls Redis cache first, falls back to scanning Maildir/new. WebSocket pushes new mail instantly — avoids polling overhead. Deploy with gunicorn --workers 4 --bind 127.0.0.1:8000 api:app behind nginx reverse proxy with rate limiting (limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s).

Automated Expiration and Disk Management

  1. Cron job every minute: python3 /app/cleanup.py — deletes inboxes where expires_at < now, removes Maildir directories, purges SQLite rows.
  2. logrotate for /var/log/mail.log, /var/log/dovecot.log — weekly, compress, keep 4 weeks.
  3. Monitor disk with df -h /var/mail in cron; alert at 80% via webhook to Slack/Discord.

SPF, DKIM, DMARC for Deliverability

Add TXT records: v=spf1 ip4:YOUR_VPS_IP -all. Generate DKIM key: opendkim-genkey -d temp.yourdomain.com -s mail -b 2048. Publish mail._domainkey TXT with public key. Postfix: milter_default_action = accept, smtpd_milters = inet:127.0.0.1:8891 (opendkim). DMARC: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com. Test with mail-tester.com — aim for 9/10 score.

Comparison: Self-Hosted vs Managed Temporary Email Services

Self-hosted backends trade operational effort for cost savings and flexibility. Managed APIs abstract infrastructure but impose limits and recurring fees. The table below compares real-world metrics for a 50K inboxes/month workload.

FactorSelf-Hosted (This Guide)Managed API (Mailgun/EmailLabs)
Monthly Cost$5–$10 (VPS + domain)$150–$400 (per 50K emails)
Max Inbox TTLCustom (seconds to years)Fixed (typically 1–24 hours)
Webhook on ReceiptYes, unlimitedYes, often metered
Attachment HandlingFull control (strip/store/forward)Size limits (25–50MB), extra fees
IP Reputation ControlDedicated IP, your responsibilityShared pools, vendor managed
GDPR Data ResidencyChoose any regionVendor-dependent (often US/EU only)
Setup Time2–4 hours first deploy15 minutes API integration
Scaling TriggerCPU/RAM/disk at 70%Auto, but cost scales linearly

Common Mistakes and How to Fix Them

Mistake: Skipping Reverse DNS and PTR Records

Why It Hurts: Major providers (Gmail, Outlook, Yahoo) reject mail from IPs without matching PTR. Your temporary emails bounce silently. Fix: Set PTR in VPS control panel to mail.temp.yourdomain.com. Verify with dig -x YOUR_IP. Confirm Postfix myhostname matches exactly.

Mistake: No Rate Limiting on Inbox Creation

Why It Hurts: Bots spin 10K inboxes/minute, filling disk and triggering spamhaus listing. Fix: Nginx limit_req on POST /inbox (10/minute/IP). Redis-backed sliding window in API: reject if INCRIBY ip:count > 20 in 60s. Ban repeat offenders via fail2ban custom filter on 429 responses.

Mistake: Storing Attachments in Database Blobs

Why It Hurts: SQLite bloats to GBs, backups fail, memory spikes on SELECT *. Fix: Save attachments to /var/mail/attachments/{inbox_id}/{sha256}. Store only path+metadata in DB. Add cron to purge orphaned files nightly.

Mistake: Ignoring IPv6 Configuration

Why It Hurts: 35% of email traffic uses IPv6 (Google 2023 data). Missing AAAA/PTR causes delays or rejection. Fix: Enable IPv6 on VPS, add AAAA record for mail.temp.yourdomain.com, set inet_protocols = all in Postfix main.cf, configure IPv6 PTR with hosting provider.

Pro Tips

  • Use postfwd (policy daemon) for complex SMTP-time rules: reject if recipient domain is in your blocklist, or if sender has >5 RCPT TO in session.
  • Implement BATV (Bounce Address Tag Validation) to prevent backscatter spam from forged sender addresses using your domain.
  • Run rspamd instead of spamassassin — 10x faster, neural network scoring, built-in DKIM signing/verification.
  • Expose Prometheus metrics (/metrics) from Python API: inboxes_active, emails_received_total, disk_usage_bytes. Alert on anomalies.
  • Backup strategy: daily rsync --link-dest to offsite storage (Backblaze B2 $5/TB). Test restore quarterly.

FAQ

What is a temporary email service backend?

A temporary email service backend is the server infrastructure that receives, stores, and serves short-lived email addresses. It consists of an MTA (Postfix) to accept SMTP mail, an MDA (Dovecot) to store messages in Maildir format, and an application layer that creates disposable addresses, enforces TTL, and exposes inboxes via API or web UI.

How does a self-hosted temporary email backend differ from Guerrilla Mail or 10 Minute Mail?

Public services like Guerrilla Mail share IPs across millions of users, causing frequent blocklisting. A self-hosted backend uses your dedicated IP, custom retention rules, private API, and zero third-party data access. You control abuse limits, attachment handling, and compliance — public services offer none of these.

Can I build this without Linux sysadmin experience?

Basic Linux skills (SSH, apt, systemctl, vim/nano) are required. The guide provides exact commands for Ubuntu 22.04. If unfamiliar, practice on a local VM first. Managed alternatives like Postal or Mailcow provide Docker-based email stacks with web UIs, reducing CLI work but increasing resource needs (2GB+ RAM).

Why are my temporary emails going to spam or bouncing?

Common causes: missing SPF/DKIM/DMARC, no reverse DNS, IP on blocklist (check multiRBL.valli.org), or recipient domain greylisting new senders. Fix: implement all three auth records, verify PTR matches hostname, warm IP with 50–100 legitimate emails/day for two weeks before full volume.

What happens when the service needs to scale beyond one VPS?

At ~200K inboxes/day, separate components: Postfix on dedicated SMTP nodes (HAProxy load balanced), Dovecot on shared NFS or object storage (MinIO), API stateless behind load balancer, Redis cluster for cache, PostgreSQL replacing SQLite. Use Ansible for reproducible deploys. Cost shifts from $5 to $100–$200/month.

Conclusion

Building a temporary email backend on a budget gives you full control over cost, features, and data — critical for privacy-focused products, QA automation, and spam-free testing. The Postfix + Dovecot + SQLite stack on a $5 VPS handles 50K daily inboxes with room to grow. Key steps: harden the server, configure catchall routing, implement TTL cleanup, and secure with SPF/DKIM/DMARC. Avoid common pitfalls like missing PTR records, no rate limits, and blob storage. Start small, monitor metrics, and scale components independently when thresholds hit.

  • Total annual cost under $60 vs $500+ for managed APIs at equivalent volume
  • Custom retention, webhooks, and attachment logic impossible on public services
  • Dedicated IP and auth records protect deliverability and reputation
  • Open-source stack avoids vendor lock-in and supports GDPR data residency

Sources

Share:

0 comments:

Post a Comment