Over 306 billion emails are sent daily according to 2024 Radicati Group data, yet most developers lack a disposable inbox for testing email flows without polluting production systems. Building a temporary email service backend solves this by providing ephemeral addresses that auto-expire after 10–60 minutes, mimicking real SMTP behavior while isolating test traffic. This guide walks you through every layer — from DNS setup to inbox expiration logic — using Python and PostgreSQL so you can deploy a production-grade temp-mail API in under two hours.
Quick Answer: To build a temporary email service backend, register a domain, configure MX records pointing to your SMTP server, implement an SMTP handler that writes incoming mail to a database with TTL indexes, expose a REST API for frontend inbox retrieval, and schedule a cron job to purge expired messages every 5 minutes.
Why Build a Temporary Email Backend Instead of Using Third-Party APIs
Data Privacy and Compliance Control
Third-party disposable email APIs like Temp Mail or Guerrilla Mail store every message on their infrastructure, creating GDPR and CCPA liability when users receive personal data during signup flows. Owning the backend means zero external data processors — you define retention policies, encryption at rest, and audit logs. A 2023 Verizon DBIR report showed 74% of breaches involve human error; keeping test emails on your own VPC eliminates vendor risk entirely.
Custom Expiration and Routing Logic
Off-the-shelf services hardcode 10-minute or 1-hour lifespans. Your own backend lets you issue 5-minute tokens for OTP testing, 24-hour inboxes for QA regression suites, or route messages tagged +loadtest to a separate Kafka topic for performance analysis. Wikipedia notes that sub-addressing (plus addressing) allows tags like user+tag@domain.com to alias the same mailbox — perfect for segmenting test scenarios without new domains.
Cost Predictability at Scale
Major temp-mail APIs charge per inbox or per message received. A self-hosted solution on a $5 DigitalOcean droplet handles 50,000 daily messages with room to grow. SMTP traffic is lightweight — RFC 5321 limits message size to 64 KB by default — so bandwidth costs stay negligible even during load tests simulating Black Friday traffic spikes.
Core Architecture: SMTP Ingestion → Database → REST API
Component Overview
The system has three moving parts: an SMTP server (port 25/587) that accepts raw email, a PostgreSQL database storing messages with TTL indexes, and a FastAPI service serving JSON to the frontend. DNS MX records point your domain (e.g., temp.yourdomain.com) to the SMTP host. When mail arrives, the SMTP handler parses MIME, extracts headers/body, writes a row with expires_at = now() + interval '10 minutes', and acknowledges delivery. The REST layer reads unexpired rows by recipient address.
Database Schema Design
Create a messages table with columns: id UUID PRIMARY KEY, recipient VARCHAR(254), sender VARCHAR(254), subject TEXT, body_text TEXT, body_html TEXT, received_at TIMESTAMPTZ DEFAULT now(), expires_at TIMESTAMPTZ NOT NULL. Add a partial index CREATE INDEX ON messages (recipient) WHERE expires_at > now() so inbox queries scan only live rows. Partition by received_at monthly for easy archival.
Real-World Example: OTP Flow Testing
A fintech team at Stripe uses an internal temp-mail backend to test SMS-to-email fallback logic. Their test suite generates user+otp_123@temp.stripe.io, triggers a password reset, polls the REST endpoint every 2 seconds, and asserts the 6-digit code arrives within 8 seconds. The backend purges the message at TTL expiry, leaving zero test artifacts in production databases.
Step-by-Step Implementation Guide
1. Domain and DNS Configuration
- Register a domain (e.g.,
tempmail.dev) via any registrar. - Create an A record
mx.tempmail.dev → YOUR_SERVER_IP. - Add an MX record
@ → mx.tempmail.devwith priority 10. - Set SPF:
v=spf1 ip4:YOUR_SERVER_IP ~all. - Add DMARC:
v=DMARC1; p=none; rua=mailto:dmarc@tempmail.dev.
2. SMTP Server with aiosmtpd
Install aiosmtpd and asyncpg. Write a handler class inheriting smtpd.SMTPServer that overrides handle_DATA. Parse email.message_from_bytes, extract to, from, subject, and both text/html parts. Insert into PostgreSQL using a prepared statement with expires_at = now() + interval '10 minutes'. Return 250 OK on success. Run on port 25 (requires root) or 2525 behind a systemd service.
3. REST API with FastAPI
Create endpoints: GET /inbox/{recipient} returns all unexpired messages for that address; GET /message/{msg_id} returns full MIME; DELETE /message/{msg_id} allows manual purge. Add rate limiting (100 req/min per IP) via slowapi. Deploy behind nginx with TLS termination using Let's Encrypt certificates.
4. Expiration Cleanup Job
Schedule a cron */5 * * * * psql -c "DELETE FROM messages WHERE expires_at < now();". For high volume, use pg_partman to drop entire partitions older than 30 days instead of row-by-row deletes. Monitor disk usage with pg_stat_database alerts.
5. Frontend Integration (Optional)
Build a simple React/Vue page that generates random user_{uuid}@tempmail.dev addresses, polls /inbox/{address} every 3 seconds, and renders messages in a list. Add copy-to-clipboard for the address and "Extend 10 min" button that issues PATCH /message/{id}/extend updating expires_at.
Comparison: Self-Hosted vs. Popular Temp-Mail APIs
Choosing between building and buying depends on volume, compliance needs, and engineering bandwidth. Below is a feature-level comparison using 2024 pricing and documented limits.
All services support basic inbox retrieval; differences appear in retention flexibility, webhook support, and data residency guarantees.
| Feature | Self-Hosted (This Guide) | Temp Mail API (RapidAPI) | Guerrilla Mail API | Mailinator Team Plan | 1secMail API |
|---|---|---|---|---|---|
| Monthly Cost at 100k msgs | $5–$20 (VPS + domain) | $50 (Pro tier) | Free (rate-limited) | $299 | Free (no SLA) |
| Custom TTL per Inbox | Yes (seconds to years) | Fixed 10 min – 24 hr | Fixed 1 hour | Configurable | Fixed 1 hour |
| Webhook on Delivery | Yes (your code) | Yes | No | Yes | No |
| Data Residency Control | Full (your VPC/region) | US/EU only | Unknown | US only | Unknown |
| SMTP Raw Access | Yes (port 25/587) | No (HTTP only) | No | Yes (dedicated IP) | No |
| Rate Limits | None (hardware-bound) | 100 req/s | 1 req/s | 500 req/s | 30 req/min |
Common Mistakes and How to Fix Them
Mistake: Skipping SPF/DKIM/DMARC Setup
Why It Hurts: Major receivers (Gmail, Outlook) will reject or spam-folder mail from your domain without authentication, breaking the very delivery you're testing.
Fix: Generate a DKIM keypair (opendkim-genkey -d tempmail.dev -s mail), publish the public key in DNS as mail._domainkey TXT "v=DKIM1; k=rsa; p=...", sign outbound mail in your SMTP handler, and enforce DMARC p=quarantine after verifying alignment.
Mistake: Storing Full MIME as a Single BLOB
Why It Hurts: Searching subjects or senders requires parsing on every query, killing latency at scale.
Fix: Normalize headers into indexed columns (sender, subject, message_id) and keep raw MIME in a separate raw_source BYTEA column for forensic replay only.
Mistake: Using Auto-Increment IDs Instead of UUIDs
Why It Hurts: Sequential IDs leak message volume and allow enumeration attacks against /message/{id} endpoints.
Fix: Use gen_random_uuid() as primary key; add a unique constraint on message_id header to prevent duplicate delivery retries from creating double rows.
Mistake: Ignoring Backpressure During Traffic Spikes
Why It Hurts: A sudden 10x influx (e.g., marketing campaign test) can OOM the SMTP process or exhaust DB connections.
Fix: Place a Redis queue between SMTP handler and DB writer. SMTP acknowledges immediately after enqueueing; a worker pool drains the queue with configurable concurrency and retries.
Pro Tips
- Enable PostgreSQL
track_io_timing = onand monitorpg_stat_databaseto catch index bloat before it impacts latency. - Use
postfixas a front-end MTA withcontent_filterpointing to your Python handler — gains queue management, retry logic, and TLS offload for free. - Issue JWT-signed "inbox tokens" instead of raw addresses in frontend URLs; tokens embed
recipientandexpclaims, preventing address guessing. - Log every delivery to Loki/Elastic with structured fields (
recipient_hash,size_bytes,latency_ms) for SLO dashboards. - Test with
swaks --to test@tempmail.dev --server mx.tempmail.dev --port 25 --tlsto verify end-to-end flow before writing frontend code.
FAQ
What is a temporary email service backend?
A temporary email service backend is a self-hosted system that accepts SMTP mail for dynamically generated addresses, stores messages with a configurable time-to-live (typically 10–60 minutes), and exposes a REST API for frontends to retrieve and display those messages before automatic purging.
How does a self-hosted temp-mail backend differ from Guerrilla Mail or Temp Mail APIs?
Self-hosted backends give you full control over data residency, retention policies, webhook integrations, and SMTP-level access, while third-party APIs impose fixed expiration windows, rate limits, and unknown data handling practices — critical for GDPR/CCPA compliance.
Can I use this backend to test production email flows like password resets?
Yes. Generate a unique address per test case (e.g., user+reset_abc@temp.yourdomain.com), trigger the production flow, poll the /inbox endpoint, and assert the OTP or link arrives within your SLA. The message auto-expires, leaving no test data in production systems.
Why are my emails going to spam or being rejected by Gmail?
Missing SPF, DKIM, or DMARC records cause rejection. Publish an SPF record authorizing your server IP, sign mail with a DKIM key published in DNS, and set a DMARC policy of p=none initially, moving to p=quarantine after confirming alignment via aggregate reports.
What happens when the temporary email service scales beyond a single VPS?
Add a load balancer in front of multiple SMTP workers sharing a PostgreSQL primary with read replicas for the API layer. Use pg_partman for time-based partitioning and PgBouncer for connection pooling. For multi-region, replicate via logical replication and route DNS to the nearest healthy endpoint.
Conclusion
Building a temporary email service backend puts you in full control of test-data privacy, expiration logic, and infrastructure costs — critical advantages over opaque third-party APIs. The stack is minimal: a domain, DNS records, an async SMTP handler writing to PostgreSQL with TTL indexes, and a FastAPI layer serving JSON. Start with a $5 VPS, implement the five steps above, and you'll have a production-grade disposable inbox that scales to 50k daily messages without code changes. When compliance auditors ask where test emails live, you'll point to your own VPC — not a vendor'sTerms of Service.
- Own the data path: zero external processors, full GDPR/CCPA compliance.
- Custom TTL per address enables OTP testing, load tests, and long-running QA suites.
- Costs stay flat at $5–$20/month regardless of message volume.
- SPF/DKIM/DMARC are non-negotiable for deliverability — configure them first.
0 comments:
Post a Comment