EmailLM: How I Solved My Spam Problem with Local AI

March 29, 2026 at 5:55 PM CSTWayne Workman8 min read

The Problem

EmailLM was created out of frustration.

Like a lot of people, I get a lot of spam in my inbox. I unsubscribe from many things but it just keeps coming somehow. Occasionally I get a poorly constructed phishing attempt in my inbox. Every day, I would get several dozens of just junk. Things I don't really care about, like order receipts, shipping updates. There's only so much will power available to locate the unsubscribe link in all these emails and then navigate whatever poorly constructed web interface there is to actually get off of said list. The emails would just pile up. Important things would get buried in the noise.

People who use Gmail don't have these problems because Gmail automagically sorts your email into "Primary", "Promotions", "Social", and "Updates". I don't use Gmail - I run my own email server using iRedMail. It comes with Spam Assassin but so many things slip through. The result? My inbox has looked like the kitchen junk drawer for the last decade. Blah.

The Epiphany

Recently I bought the NVIDIA RTX Pro 6000 Blackwell 96GB card and installed it into my Ubuntu 24 tower. Via vLLM I've been running a mixture of Qwen3.5-35B-A3B and Qwen3.5-27B basically constantly, either one or the other (only one fits at a time). vLLM offers an OpenAI compatible API for inference, and it's really performant and memory efficient. I've been running the card at basically 100% GPU since it was installed - most of that is from generating synthetic data for my from-scratch LLM endeavors.

Though while I sat at my desktop looking at the mountain of email and loathing going through it yet again, it hit me.

I can have my locally running copy of Qwen3.5 sort all of these emails for me. And my privacy would be preserved because it'd all be local.

The Build

The race started. I stopped the synthetic data generation jobs and killed the Qwen3.5-35B-A3B vLLM session and started the Qwen3.5-27B session (it's better at coding). I created a new poorly named private github repo "email-spam-filter". An entire evening went by, coding with Qwen3.5 27B via Continue Dev CLI, all locally. At the end of the evening, I had a script that logged into my inbox via encrypted IMAP and collected everything from my inbox for inference and had my local LLM sorting emails into a few subfolders underneath my Inbox. It was working.

The next evening, I added yet more features. DKIM and SPF validation - if an email failed these checks, it automatically went to spam. I added prompt injection detection and a folder for just those. I added config file, I integrated KeePassXC for storing email usernames/passwords. I added CRON execution, and better logging. I added multi-inbox support, global and inbox level allow lists. Configurable categories and folders. Configurable prompts per category. I added duplicate-process protection. Things were working very well.

The next evening I prompted Qwen3.5 27B to look for security problems - it found many. I had Qwen fix most of them. The next thing was unit tests, also written by Qwen. Then I changed the project name throughout to the more fancy "EmailLM".

The repo is now public and MIT licensed

Located here: https://github.com/wayneworkman/emaillm

The project isnt perfect. In fact it has quite a few imperfections and could use a lot more love. Contributions are certainly welcome. That said, it works. And it can be yours too.

I believe my spam problems are solved forever now, not a single piece of spam has slipped through since this script has been running. And it categorized its first phishing attempt correctly.

This is what's possible now with local inference. In just one evening using an open-weights model, fully offline, you can create working solutions that solve real problems in your life, while maintaining security because you're not sending your personal data to a 3rd party.

Anything that you do frequently that is a relatively straightforward task that you don't want to do, and is done on a computer, can most likely be automated away with a local LLM.

← Back to Blog