Fixing email spam with AI: When traditional filters aren't enough
I've used Fastmail for years. Brilliant service, sensible pricing, no ads or tracking. But the spam filtering? Wildly inconsistent.
The problem isn't traditional spam—Fastmail catches most of that fine. Mismatched DKIM/SPF records? Blocked. Blacklisted domains? Filtered. That all works.
The problem is everything else that gets through. A phishing email from a legitimate gmail.com address pretending to be Netflix. A marketing campaign from some company I've never heard of that somehow got my email address. These pass all the technical checks—proper authentication, clean sender reputation—but they're still unwanted garbage cluttering my inbox.
The modern spam problem
Here's what lands in my inbox regularly:
- "We redesigned your website" spam from what looks like legitimate agencies
- SEO companies promising to boost my rankings
- Marketing emails I definitely never subscribed to
- Newsletter spam that's professionally designed but completely irrelevant
These don't trigger traditional spam filters. They come from valid domains or even gmail.com and outlook.com addresses. They have proper SPF and DKIM records. The grammar is perfect. By all technical measures, they're legitimate emails—just completely unwanted.
And this is where it gets interesting: 89% of malicious emails bypass SPF, DKIM and DMARC authentication1. These authentication protocols were meant to solve email fraud, but spammers have adapted. They're using legitimate infrastructure now.
What actually needs filtering
The problem isn't just "spam reduction". It's more nuanced:
Phishing: Fraudulent emails with links that don't match the claimed brand. I get a steady stream of fake "Netflix" and "Spotify" emails asking me to update payment details. These are getting better—proper formatting, convincing language, domains that look almost right. Traditional filters catch some, but the sophisticated ones slip through. Fastmail does not catch these at all.
Traditional spam: Domain spoofing where the email claims to be from one domain but actually comes from another. SPF/DKIM checks catch these easily enough. Not the real problem.
Junk: This is where it all falls apart. Legitimate-looking emails from real domains—actual gmail.com or outlook.com addresses—that are just unsolicited marketing garbage. "We noticed your website needs redesigning." "Let us handle your SEO." "Exclusive offer for business owners." They pass authentication because they're sent from real infrastructure. They're grammatically correct. They look professional. But I never asked for them, never subscribed, and they're cluttering my inbox. These need content analysis, not just header inspection.
The numbers tell the story
The scale of this problem is enormous. Around 47% of all email traffic is spam as of 20242. That's 160 billion spam emails sent every day globally3. Gmail alone blocks 15 billion spam emails daily with their AI-powered filters, achieving a 99.9% catch rate4.
But here's the kicker: Google blocked 265 billion unauthenticated emails in 20245 because they're easy to spot. The authenticated spam? That's harder.
Only 33.4% of the top 1 million domains have DMARC records, and of those, 57.2% use the toothless p=none policy that does nothing6. That means 85.7% of domains have no effective DMARC protection. Spammers know this and exploit it ruthlessly.
But here's the kicker: 89% of malicious emails bypass SPF, DKIM and DMARC authentication1. These authentication protocols were meant to solve email fraud, but spammers have adapted. They're using legitimate infrastructure now.
The numbers are stark. Looking at what actually gets through, the spam breakdown tells an interesting story:
Fastmail's approach (and why it's not enough)
Fastmail uses SpamAssassin combined with their own Vade content filter7. It's a solid setup—SpamAssassin has been around forever and works well for traditional spam. The Vade filter adds pattern matching and keeps updating rules based on current threats.
But here's where it falls apart: the learning function is backwards. If you use a mail client like iOS Mail, you can't just hit "Spam" to train the filter. Instead, you have to8:
- Create a special folder
- Go to Settings → Folders and enable "Scan this folder daily and learn any new messages"
- Set it to learn "as spam"
- Manually move spam there
I don't want to use Fastmail's web client—I want to use their hosting with my own mail client. The friction here means I just... don't train it. Which means the filter never improves.
Why AI actually makes sense here
Traditional spam filters work on rules and patterns. But this grey area requires understanding context and intent—exactly what large language models excel at.
AI handles ambiguity well. It can read an email and understand whether it's a genuine business enquiry or another generic "we can redesign your website" pitch. It understands urgency tactics, it spots mismatched context, it catches the subtleties that rule-based systems miss.
Building it
I wanted to test the idea before committing to infrastructure. So I exported a few hundred .eml files from my Fastmail inbox and built a test harness using Ollama running Llama 3.1 8B locally.
The process had two parts:
Manual labelling: I went through my exported emails and manually categorised them—personal, transactional, newsletter, marketing, spam, phishing, etc. This gave me ground truth to test against.
Model evaluation: I ran the same emails through the LLM with a carefully crafted prompt asking it to categorise and score each one. Then I compared the model's classifications against my manual labels to see where it succeeded and where it failed.
This let me iterate on the prompt without burning through API credits or dealing with deployment complexity. Once I had accuracy above 85% and false positives below 5%, I knew it was worth deploying.
The production version is a Cloudflare Worker that:
- Intercepts incoming email via Cloudflare Email Routing
- Extracts sender, subject and body
- Analyses content using
@cf/meta/llama-3.1-8b-instructvia Workers AI - Categorises the email and assigns a spam score (0-10)
- Adds headers:
X-Wh-Spamscore,X-Wh-CategoryandX-Wh-Reasoning - Forwards to Fastmail with headers intact
I'm using Llama 3.1 8B because it's quick (sub-second inference) and good enough at understanding the nuance between legitimate communication and marketing garbage.
Categories and scoring
The AI sorts emails into ten types:
- personal: Personal correspondence
- transactional: Order confirmations, password resets, receipts
- newsletter: Legitimate newsletters I've subscribed to
- marketing: Promotional emails, sales pitches
- social: Social media notifications
- automated: System notifications, monitoring alerts
- phishing: Suspected credential harvesting
- scam: Get-rich-quick schemes, urgent payment requests
- spam: Generic unwanted bulk email
- suspicious: Unclear intent but potentially malicious
Spam scores run 0-10:
- 0-2: Clean, legitimate email
- 3-4: Probably legitimate but commercial
- 5-6: Suspicious characteristics
- 7-8: Likely phishing or scam
- 9-10: Definite threat
Early results
I haven't deployed this to production yet, but I've run it against recent messages in my inbox by exporting the emails from Mac Mail.
Here are the preliminary results:
| Category | Count | Avg Score | False Positives |
|---|---|---|---|
| Personal | 326 | 0.88 | 1 |
| Transactional | 708 | 0.28 | 10 |
| Newsletter | 462 | 1.55 | 2 |
| Marketing | 353 | 2.91 | 9 |
| Social | 272 | 0.62 | 9 |
| Automated | 163 | 1.83 | 9 |
| Phishing | 272 | 9.32 | 1 |
| Scam | 82 | 8.69 | 2 |
| Spam | 54 | 7.63 | 0 |
| Suspicious | 27 | 5.76 | 2 |
| Total | 2,719 | — | 45 |
The implementation
The worker handles email interception, AI analysis and forwarding. Key features:
- Extracts email body intelligently (handles multipart, base64, quoted-printable)
- Truncates to 2,500 characters for performance (preserving full links and sentences)
- Comprehensive prompt engineering to guide AI analysis
- Robust error handling—if AI fails, forwards with safe defaults
- Validates outputs to ensure scores stay 0-10 and categories are valid
The prompt explains all categories, scoring guidelines and red flags. It emphasises low false positives for personal and transactional emails—the last thing you want is legitimate email marked as spam.
I haven't included a step to detect for prompt injection attacks, but I imagine a commercial implementation would need that layer of security.
Why this matters
Google and Yahoo now require DMARC for bulk senders (5,000+ emails/day)9. They enforce a 0.3% spam complaint threshold10. Authentication is table stakes now.
But authentication alone isn't enough. 89% of malicious emails pass authentication checks1. Spammers use legitimate infrastructure. They know the rules and play within them.
The missing piece is content introspection. Understanding what an email is actually trying to do, not just where it came from. That's where AI comes in.
I've uploaded the repository to Github: willhackett/email-filtering with instructions on how to deploy it yourself and test against your own inbox.
- Keepnet, 2025 Phishing Statistics, August 2025 ↩
- Mailmodo, 23 Email Spam Statistics to Know in 2025, March 2025 ↩
- EmailToolTester, Spam Statistics 2025, October 2024 ↩
- SQ Magazine, Email Spam Statistics 2025, September 2025 ↩
- Keepnet, 2025 Phishing Statistics, August 2025 ↩
- DMARC Checker, SPF, DKIM, and DMARC in 2024: Analyzing the Top 1M Domains, 2024 ↩
- Fastmail, Spam filtering ↩
- Fastmail, Improving spam protection ↩
- PowerDMARC, Google and Yahoo Email Authentication Requirements 2025, August 2025 ↩
- Sinch Mailgun, State of email deliverability 2025, 2025 ↩