How We Built a Serverless Temp Mail Using Cloudflare Workers (Zero Cost)
A deep dive into building a completely serverless temporary email service using Cloudflare Workers, Email Routing, and KV storage - all within the free tier.
The Challenge
Building a temporary email service sounds simple until you realize you need:
- A mail server to receive emails
- Storage for those emails
- An API to serve them
- A frontend for users
- All of this needs to scale and be reliable
Traditional approaches require VPS servers, mail transfer agents like Postfix, databases, and ongoing maintenance. Costs add up quickly.
We built TmpMail entirely on Cloudflare's edge infrastructure—and the free tier covers everything.
The Architecture
┌─────────────────┐
│ Email Sender │
└────────┬────────┘
│
┌────────▼────────┐
│ Cloudflare │
│ Email Routing │
└────────┬────────┘
│
┌────────▼────────┐
│ Email Worker │
│ (Processing) │
└────────┬────────┘
│
┌────────▼────────┐
│ Cloudflare KV │
│ (Storage) │
└────────┬────────┘
│
┌──────────────┐ ┌────────▼────────┐
│ Frontend │◄───│ API Worker │
│ (Pages) │ │ (REST API) │
└──────────────┘ └─────────────────┘
- Enable Email Routing
- Create a catch-all rule that sends to a Worker
The magic is that Cloudflare handles all the MX record complexity and spam filtering.
Component 2: Email Worker
When an email arrives, our Worker processes it:
export default {
async email(message: EmailMessage, env: Env) {
const to = message.to;
const from = message.from;
Component 1: Email Routing
Cloudflare Email Routing lets you receive emails at your domain and route them to Workers. Here's the setup:
1. Add your domain to Cloudflare
// Parse the email content const rawEmail = await new Response(message.raw).text(); const parsed = await parseEmail(rawEmail);
// Extract verification codes const codes = extractCodes(parsed.text || parsed.html); const links = extractLinks(parsed.html);
// Store in KV const emailData = { id: crypto.randomUUID(), from, subject: parsed.subject, textContent: parsed.text, htmlContent: sanitizeHtml(parsed.html), extracted: { codes, links }, receivedAt: new Date().toISOString(), };
await env.EMAILS_KV.put(
email:${inboxId}:${emailData.id},
JSON.stringify(emailData),
{ expirationTtl: 86400 } // 24 hours
);
}
}
Component 3: Smart Extraction
The secret sauce is our code extraction logic. We maintain templates for popular services:
const templates = {
'github.com': {
codePattern: /verification code is: (\d{6})/i,
linkPattern: /https:\/\/github\.com\/.*verify/g,
},
'google.com': {
codePattern: /(\d{6}) is your Google verification code/,
},
// ... dozens more
};function extractCodes(text: string, senderDomain: string): string[] {
// Try template-specific extraction first
const template = templates[senderDomain];
if (template?.codePattern) {
const match = text.match(template.codePattern);
if (match) return [match[1]];
}
// Fall back to generic patterns
const genericPatterns = [
/\b(\d{4,8})\b.*(?:code|verify|confirm)/i,
/(?:code|verify|confirm).*\b(\d{4,8})\b/i,
];
for (const pattern of genericPatterns) {
const match = text.match(pattern);
if (match) return [match[1]];
}
return [];
}
Component 4: KV Storage
Cloudflare KV is perfect for this use case:
- Automatic expiration - Set TTL and emails delete themselves
Our KV schema:
inbox:{inboxId} → InboxMetadataComponent 5: API Worker
The REST API is straightforward:
router.post('/api/inbox', async (req, env) => {
const inboxId = generateInboxId(); // e.g., "alex1234"
const token = generateToken(); // 32-char random string
const email = ${inboxId}@get-a-temp-email.xyz; await env.KV.put(inbox:${inboxId}, JSON.stringify({
email, createdAt: new Date().toISOString(),
expiresAt: new Date(Date.now() + 86400000).toISOString(),
}), { expirationTtl: 86400 });
await env.KV.put(token:${token}, JSON.stringify({
inboxId, domain: 'get-a-temp-email.xyz',
}), { expirationTtl: 86400 });
return { success: true, data: { token, email } };
});
The Result
- Zero server costs - Everything runs on Cloudflare free tier
Limitations
It's not all perfect:
1. KV eventual consistency - Emails might take 1-2 seconds to appear
Try It Yourself
The architecture is simple enough that you could build it yourself:
1. Sign up for Cloudflare (free)
Or just use TmpMail and let us handle it!
---
*Questions about the architecture? Reach out at admin@get-a-temp-email.xyz*
Ready to try TmpMail?
Get a disposable email address in seconds. No signup required.
Create Temp Email