STATUS ÜBERPRÜFEN
I AM LISTENING TO
|

The Best IMAP Filter Solutions: Howto Finally Get Your INBOX Under Control

31. August 2026
.SHARE

Table of Contents

Let’s be real about email: it’s out of control. The average person gets over 120 emails a day. Newsletters you forgot you subscribed to, receipts from three years ago, notifications from every app that ever got your address, and somewhere in there — buried under all of it — maybe four or five messages from actual humans who need an actual reply. You’ve tried folders. You’ve tried labels. You’ve tried inbox zero. None of it sticks, because the problem isn’t your workflow. It’s that nobody is filtering for you.

Most email providers offer some form of server-side filtering — Gmail has its label rules, Fastmail has Sieve, and self-hosted setups have whatever you configure. But what if your provider’s filtering is too basic? What if you use multiple accounts across different providers and want consistent rules everywhere? What if you want filtering logic that goes way beyond „from contains“ and „subject matches“? That’s where IMAP-based filtering comes in.

IMAP filtering runs on a machine you control — a VPS, a home server, a Raspberry Pi, or a Docker container — and connects to your mailboxes over standard IMAP. It doesn’t care which email client you use, which provider hosts your mail, or whether your server supports Sieve. It works everywhere, for every account, with rules as simple or as complex as you want them to be. From basic „move all newsletters to this folder“ to AI-powered classification and Lua scripting with full regex power — there’s an IMAP filter solution for every skill level and use case. Here’s my deep dive into the landscape.

Why IMAP Filtering?

If you’ve never used server-side email filtering before, here’s why it’s worth the setup time:

  • Works with any email provider — Gmail, Fastmail, iCloud, Proton Mail (via Bridge), self-hosted Dovecot, Microsoft 365, or your ISP’s crusty old IMAP server. If it speaks IMAP, it works. No Sieve or server-side plugin required.
  • Cross-client, client-independent — Your filters run on a server somewhere, not inside Apple Mail or Thunderbird. Switch clients, use your phone, check webmail — the rules apply everywhere, all the time.
  • Lua scripting gives you unlimited rule complexity — With imapfilter as the engine, you’re writing real code, not clicking through a GUI wizard. Regular expressions on headers and body text, age-based conditions, multi-condition logic with AND/OR chaining, moving mail between accounts on different servers — all of it is possible.
  • Runs anywhere — Docker container on your NAS, systemd service on a VPS, cron job on a Raspberry Pi. Once it’s set up, you forget it exists.
  • GDPR-friendly by default — Your rules and your mail access credentials stay on hardware you control, under your jurisdiction. No third-party service reads your inbox.
  • Free and open source — Every tool in this guide is open source. No subscriptions, no API pricing tiers, no „pro“ upsells. Just working code.

imapfilter: The Engine Under the Hood

Almost everything in the IMAP filtering world runs on imapfilter, a C application by Eleftherios Chatzimparmpas that connects to remote IMAP servers and processes mailboxes using rules written in Lua. It’s been around since 2001, it’s actively maintained, and it’s the foundation of this entire ecosystem. Think of it as the SpamAssassin or Rspamd of general-purpose mail filtering — battle-tested, deeply capable, and scriptable.

Here’s what a minimal imapfilter config looks like — connect to an account, grab unseen mail, move newsletters to a folder:

That’s the basics. But imapfilter goes much deeper. You can chain conditions with * (AND) and + (OR), subtract with - (NOT), match against headers with regex, check message age and size, flag messages as seen or important, and even move mail between accounts on completely different servers. The official sample configs show patterns for daemon mode, error recovery with automatic reconnect, OAuth2 authentication for Gmail, and calling external programs via pipe_from(). If you can describe the rule in Lua, imapfilter can execute it.

Running imapfilter in Docker

Running imapfilter directly on a server works fine, but Docker images add convenience: no dependency management, easy config mounting, built-in scheduling, and a clean separation between the filter engine and your host system. Here are the Docker imapfilter images worth knowing about, from most feature-rich to simplest.

ntnn/docker-imapfilter

ntnn/docker-imapfilter is the most mature and feature-complete Docker image in the imapfilter ecosystem. Its standout feature is git-based configuration — point it at a repo, and it pulls your imapfilter rules on startup. Your rules are version-controlled, shareable across machines, and you never have to SSH into a server just to tweak a filter.

It supports two run modes. In cron mode, the container runs imapfilter, sleeps for a configurable interval, then runs again. In daemon mode, it expects your Lua config to enter an idle loop using imapfilter’s native become_daemon() — the container just keeps running and lets imapfilter handle its own scheduling. Daemon mode is more efficient because it keeps IMAP connections alive between runs.

The image ships with example Docker Compose, Docker Swarm, and Kubernetes deployment configs, plus environment variables for log file output, config path, and sleep interval. If you want a production-grade imapfilter setup you can deploy and forget, this is the one.

sandipb/imapfilter-docker

sandipb/imapfilter-docker takes a different approach — built on Alpine for a tiny image footprint, focuses on file-mount config rather than git, and adds several quality-of-life features that make testing and debugging much easier. Originally forked from the eikendev image, it has since diverged significantly with its own entrypoint and validation suite.

Two features stand out. The IMAPFILTER_DRY_RUN mode runs imapfilter with the --dry-run flag so you can test new rules without actually moving or deleting anything. And the LOG_DIR environment variable lets you redirect log output to a host-mounted directory, so your filter logs survive container restarts. Extra imapfilter CLI arguments pass through with IMAPFILTER_EXTRA_ARGS for full control over the underlying invocation.

eikendev/imapfilter-docker (Archived)

eikendev/imapfilter-docker was the original Docker image that established the pattern most imapfilter containers now follow. It was archived in May 2025 and is now read-only, but it deserves a mention because both the sandipb image and several other forks trace their lineage back to it. It was also one of the few images that explicitly supported Podman alongside Docker. If you’re still running it, migrate to sandipb/imapfilter-docker or ntnn/docker-imapfilter — both are actively maintained.

oliverlorenz/docker-imapfilter

oliverlorenz/docker-imapfilter is the simplest Docker imapfilter image available — it runs imapfilter as a cron job inside the container. No daemon logic, no git integration, no complex environment variables. You pass your IMAP credentials as IMAP_USERNAME, IMAP_HOST, and IMAP_PASSWORD, mount a config file, and the container handles the rest. The cron approach means imapfilter gets invoked fresh each interval — less efficient than a persistent daemon but simpler to reason about and harder to break. If you’re new to imapfilter and just want something running in five minutes, start here.

Cybolic/docker-imapfilter-isync

Cybolic/docker-imapfilter-isync bundles imapfilter with mbsync (isync) and Supercronic in a single container. mbsync syncs IMAP mailboxes to a local Maildir — useful if you want server-side filtering plus a local backup or if you’re feeding mail into local tools like notmuch. Supercronic is a cron implementation designed for containers that handles signals correctly without a running init system. If you need filtering plus local sync in one container, this is the only off-the-shelf option.

Docker Images at a Glance

Image
Run Mode
Config Approach
Standout Feature
ntnn/docker-imapfilter
Daemon + cron
Git repo
K8s support, most mature
sandipb/imapfilter-docker
Interactive / cron
File mount
Dry-run mode, LOG_DIR
eikendev/imapfilter-docker
Interactive
File mount
Podman support (archived)
oliverlorenz/docker-imapfilter
Cron only
Env vars + mount
Simplest setup possible
Cybolic/docker-imapfilter-isync
Supercronic
File mount
mbsync + filter bundled

Advanced imapfilter Modules

Because imapfilter uses Lua as its configuration language, it’s not limited to built-in functions — you can write or import Lua modules that extend its capabilities. These three modules push imapfilter well beyond basic folder-sorting into genuinely useful automation territory.

snoozebox — The Free Sanebox Alternative

snoozebox is a Lua module that adds email snoozing to imapfilter. If you’ve used Sanebox or the snooze feature in Gmail or Spark, you know the workflow: an email arrives that you want to deal with later, so you snooze it for a day, a week, or until tomorrow morning, and it disappears from your inbox and returns at the right time. snoozebox does exactly that, but it’s free and works with any IMAP provider.

The workflow is elegant. You create a parent folder called SnoozeBox and sub-folders with names like Snooze_1d, Snooze_1w, Snooze_1m — the suffix determines the snooze duration (h for hours, d for days, w for weeks, m for months). Move an email into one of those folders, and snoozebox attaches a custom X-Snooze-Until header and moves it into a holding pen. On each run, it checks all snoozed messages and returns expired ones to your inbox, marked as unread. It even calculates intervals from the start of the current day, so snoozing something at 10pm with Snooze_1d brings it back at midnight — „snooze until tomorrow“ actually means tomorrow, not „in 24 hours.“

Setup is two functions — go_to_sleep() and wake_up() — and a few lines of Lua to wire them into your config. If you’ve ever considered paying for Sanebox just for the snooze feature, snoozebox gives you that for the cost of a Docker container.

imapfilter-llm-sort — AI-Powered Classification

imapfilter-llm-sort takes IMAP filtering into 2026 territory: it uses a large language model to classify your email and move messages into the right folders. It connects to any OpenAI-compatible API — that means OpenAI itself, but also local models via Ollama or LM Studio, or cloud APIs like Groq and Together. You define categories with descriptions (Bills, Newsletters, Personal, Work), and the LLM reads each email and decides where it belongs.

The clever bit is the SQLite classification cache. If the same Message-ID comes through again with the same config, it returns the cached result instantly without hitting the API. Change your categories or switch models, and the cache automatically ignores old entries. The classifier is intentionally conservative — if the model returns anything other than a recognized category name, the message stays in your inbox untouched. Temperature is locked at zero for deterministic results.

A macos-loop.zsh runner script handles continuous operation with configurable sleep intervals, and it supports model escalation — pass a comma-separated list of models, and if the first one fails, it falls through to the next. Running this on a local LLM via Ollama means zero API costs and no data leaving your network. Even on cloud models, the cache keeps token usage low over time.

imapscan — SpamAssassin + imapfilter in Docker

imapscan is an archived but interesting project that combined imapfilter with ISBG (the Python IMAP Spam Begone tool) and SpamAssassin in a single Docker container. On startup, it learned from your spam and ham folders to train Bayesian filters, then periodically scanned your inbox for spam. The architecture used three Docker volumes — one for SpamAssassin data, one for the imapfilter config, and one for account configuration — keeping state and rules neatly separated. While imapscan itself is no longer maintained, the pattern it established (IMAP filtering engine plus spam classifier plus Docker) lives on in antispambox, which we’ll cover in the alternatives section.

If imapfilter Isn’t Your Thing

imapfilter is powerful, but it’s not for everyone. The Lua requirement can be a barrier, and if all you want is spam filtering, there are more focused tools. Here are the best alternatives I’ve found across Python, Go, C, and server-side approaches — each with a clear use case where it beats imapfilter.

For spam solutions, see my article about some reliable solutions.

fdm — Fetch, Filter, Deliver

fdm (fetch and deliver mail) by Nicholas Marriott is the most mature non-imapfilter tool in this space, with nearly two decades of development behind it. It’s written in C, has no scripting language dependency, and takes a fetch-then-deliver approach rather than operating on mail in-place. You pull messages from IMAP, POP3, Maildir, or stdin, run them through a rich set of matching rules, and then deliver them — to Maildir, mbox, SMTP, an external command via pipe, or even back to an IMAP folder.

fdm’s rule engine is extensive: match by account, age, size, regular expression on headers and body, attachment presence, cached message tracking, and tagged or unmatched state chaining. The configuration syntax is its own domain-specific language, not Lua, so there’s no scripting involved — rules are declarative. This makes fdm a strong choice if you want imapfilter-level filtering power but would rather write a structured config file than a Lua script. It also handles the fetch part, which imapfilter doesn’t, so it’s more of an end-to-end solution if your workflow involves downloading mail locally.

imap-thingy — Python Filtering Library

imap-thingy is a Python library that takes a completely different approach: instead of a config file or scripting language, you compose filters using Python objects. A filter looks like FromIs("newsletter@example.com") & SubjectMatches(r"Weekly Digest"), and actions are chained with + — for example, MarkAsRead() + MoveTo(Path("Newsletters")). Under the hood, it uses server-side IMAP search whenever criteria support it and falls back to local body parsing with a per-run fetch cache for regex conditions.

The standout feature is multi-account support with a clean, readable syntax. You define accounts from a JSON file, reference them by name, and run filters across multiple accounts in the same script. It also ships helper functions like dmarc_pairs() that auto-generate filter pairs for common patterns like moving DMARC reports to a folder. If you’re comfortable in Python and want filtering logic that lives alongside your automation scripts rather than in a separate Lua config, imap-thingy is a natural fit. No Docker image or daemon mode exists — you’d schedule it via cron or wrap it yourself.

Sieve + Dovecot Pigeonhole — Server-Side Filtering

Sieve is the IETF standard mail filtering language (RFC 5228), and Dovecot’s Pigeonhole plugin implements it for Dovecot mail servers. This is server-side filtering in the truest sense — rules execute at delivery time, before the message even hits your inbox. It’s the gold standard for self-hosted email: zero latency between mail arrival and rule application, no polling, no external dependencies, and no credentials to manage beyond your Dovecot config.

The obvious limitation: you must control the mail server. If you’re on Gmail, Fastmail, iCloud, or any hosted provider, Sieve is not available to you — which is exactly why client-side IMAP filtering tools like imapfilter exist. But if you run your own mail server with Dovecot, or if your hosting provider offers Sieve management (some do, like Mailbox.org and Migadu), this is the way to go. The ManageSieve protocol (RFC 5804) also gives you a standard way to upload and manage scripts remotely, and several email clients including Roundcube provide GUI editors for Sieve rules.

All Solutions Compared

Here’s how every IMAP filtering tool in this guide stacks up side by side:

Solution
Language
Engine
Docker
Run Mode
Best For
imapfilter (standalone)
C + Lua config
Native IMAP
Manual
Cron / daemon
Maximum control, complex rules
ntnn/docker-imapfilter
Shell + Lua
imapfilter
Yes
Daemon + cron
Git-managed config, K8s
sandipb/imapfilter-docker
Shell + Lua
imapfilter
Yes
Interactive / cron
Testing-friendly, dry-run
oliverlorenz/docker-imapfilter
Shell + Lua
imapfilter
Yes
Cron only
Simplest Docker setup
snoozebox
Lua module
imapfilter
Manual
Depends on host
Email snoozing
imapfilter-llm-sort
Lua module
imapfilter
Manual
Loop script
AI-based classification
fdm
C
Built-in
No
Cron
Fetch + filter + deliver
imap-thingy
Python
Built-in
No
Cron
Python-native, multi-account
Sieve + Pigeonhole
Sieve
Dovecot
N/A
Delivery-time
Self-hosted mail servers

Which IMAP Filter Solution Is Right for You?

With all these options, the choice comes down to your specific situation:

  • You run your own mail server — Use Sieve with Dovecot Pigeonhole. It’s the IETF standard, runs at delivery time, and you already control the infrastructure. Don’t add an external IMAP filter when the server can do it natively.
  • You want maximum filtering power and you’re comfortable with code — imapfilter with the ntnn or sandipb Docker image. Lua gives you full programming flexibility, and Docker handles scheduling and isolation. This is the combination I use and recommend for most self-hosting enthusiasts.
  • You want to snooze emails like Sanebox without paying for it — snoozebox on top of any imapfilter setup. It’s a drop-in Lua module that adds the snooze workflow to whatever imapfilter configuration you already have.
  • You want AI to sort your inbox — imapfilter-llm-sort with a local LLM via Ollama. Zero API costs, no data leaving your network, and the SQLite cache means only genuinely new messages hit the model.
  • You need fetch + filter + local delivery in one tool — fdm. It pulls from IMAP or POP3, filters with declarative rules, and delivers to Maildir, mbox, or SMTP. The single-binary C architecture makes it fast and reliable.
  • You prefer Python over Lua for filtering logic — imap-thingy. The composable filter syntax reads like natural language, multi-account support is first-class, and you can embed filtering directly into Python automation scripts.
  • You want a web-based interface for managing accounts and rules — Roll your own with PHP and OpenSwoole, or keep reading — that’s exactly what the next section covers.

Roll Your Own: PHP + OpenSwoole IMAP Filter Daemon [My Solution]

Sometimes the off-the-shelf tools don’t quite fit. Maybe you need a web interface for non-technical users to manage their own filter rules. Maybe your filtering logic depends on database lookups, external APIs, or business logic that’s already written in PHP. Maybe you just prefer working in a language and ecosystem you know inside out. That was my situation — and the result is a working setup built on PHP with OpenSwoole as the daemon engine.

The architecture is straightforward: a PHP-based web interface handles account and rule management — add, edit, enable, disable, delete, snooze — storing everything in a database. The config is than synced to an OpenSwoole daemon that reads the configuration, connects to IMAP accounts on a configurable interval, applies matching rules, and logs results. The two components — web UI and daemon — share the same data but operate independently, so you can update rules through the browser and the daemon picks them up on its next cycle without a restart.

What Is OpenSwoole?

OpenSwoole is a high-performance coroutine-based PHP extension that enables PHP to run as a long-lived process — something traditional PHP, which boots up, handles one request, and dies, was never designed to do. It’s a fork of the original Swoole project with a focus on stability, documentation, and long-term maintainability. Among its capabilities: an async HTTP server, WebSocket server, TCP/UDP server, process management, coroutine-based concurrency, and — critically for an IMAP filter daemon — a reliable timer system via Swoole\Timer::tick().

The killer feature for this use case is that OpenSwoole keeps PHP running in memory between cycles. A traditional cron-based approach would bootstrap PHP, load the IMAP extension, open a fresh connection, scan mailboxes, apply rules, and tear everything down — on every single run. With OpenSwoole, the daemon starts once, opens persistent IMAP connections, and executes filter cycles on a timer without the overhead of PHP’s startup and shutdown on every tick. For setups with multiple accounts, this efficiency difference is significant.

The coroutine model also means you can scan multiple accounts concurrently without blocking — each account gets its own coroutine, and the daemon processes them all in parallel within a single PHP process. A typical scan of three accounts with moderate inbox sizes takes milliseconds of actual work time inside the OpenSwoole event loop once connections are established.

How the Daemon Works

The OpenSwoole daemon runs a timer that fires at a configurable interval — say, every 60 seconds. On each tick, it reads the current account and rule configuration from the database, iterates through each enabled account, connects via PHP’s built-in IMAP extension, and checks for new messages. Each rule is evaluated against every new message — conditions can include sender address patterns, subject keywords, header regex matches, message age, and custom flags — and matching messages get the configured actions applied: move to folder, mark as read, flag, delete, or forward.

Because the daemon is a proper long-running process, it handles signals for graceful shutdown, reconnects dropped IMAP connections transparently, and writes structured logs that the web UI can display as a filter history. Error handling is per-account, so a connection failure on one mailbox doesn’t block processing on the others.

The Web Interface

The PHP web frontend provides a clean UI for managing everything without touching a config file or a database directly. Accounts are configured with server, port, encryption type, username, and an app-specific password — the web interface validates connectivity on save. Rules are defined through a form-based builder that generates the underlying conditions and actions without requiring users to write code. Each rule can be toggled on or off, ordered by priority, and assigned to specific accounts or all accounts. A dashboard shows the last run status, how many messages were processed, and any errors that occurred — giving you visibility into whether your filters are actually working without SSH-ing into a server and grepping log files.

This approach won’t be for everyone — it’s more infrastructure than dropping a single Docker container into your stack. But if you need filter management with a web UI, want PHP-native tooling, or already run OpenSwoole for other services, it’s a proven pattern that combines the flexibility of a database-backed rule engine with the efficiency of a coroutine-based daemon.

Glossary

IMAP (Internet Message Access Protocol)
A standard email protocol that allows a client to access and manipulate email messages on a remote mail server without downloading them. All tools in this guide use IMAP to read, move, and flag messages server-side.
Sieve
An IETF standard mail filtering language (RFC 5228) that runs server-side at delivery time. Supported by Dovecot via the Pigeonhole plugin. Only available if you control the mail server.
Lua
A lightweight, embeddable scripting language used by imapfilter for its configuration and rule definitions. Chosen for its small footprint and easy C integration.
Maildir
A directory-based email storage format where each message is a separate file. Used by Dovecot, fdm, mbsync, and most local mail tools. Contrast with mbox, which stores all messages in a single file.
Supercronic
A cron implementation designed specifically for containers. Handles signals correctly, runs as a non-root user, and doesn’t require a running init system. Used by the Cybolic docker-imapfilter-isync image.
Daemon Mode
A long-running process that stays in memory and executes work on a schedule or in response to events, rather than being invoked fresh each time. imapfilter and OpenSwoole both support daemon operation, which is more efficient than cron-based approaches because connections persist between cycles.
ISBG (IMAP Spam Begone)
A Python script that connects to an IMAP server, scans messages with SpamAssassin, and moves detected spam to a junk folder. Also the library that antispambox wraps.
SpamAssassin
An open-source spam filtering system that uses a combination of heuristic rules, Bayesian filtering, and external network checks to score messages for spam probability. The standard backend for IMAP-based spam filtering.
Rspamd
A fast, modern spam filtering system designed as a more efficient alternative to SpamAssassin. Used by antispambox alongside SpamAssassin for speed-critical deployments.
Bayesian Filtering
A statistical classification technique used by SpamAssassin and Rspamd that learns to distinguish spam from legitimate mail by analyzing word frequencies in previously classified messages. Requires training with both spam and ham examples.
IMAP IDLE
An IMAP extension that allows the server to push notifications to the client when new mail arrives, rather than the client polling on a timer. Used by antispambox for real-time spam scanning with zero delay.
OpenSwoole
A high-performance coroutine-based PHP extension that enables PHP to run as a long-lived async server process. Forked from Swoole with a focus on stability and documentation. The daemon engine behind the custom PHP IMAP filter solution described in this guide.
Coroutine
A lightweight concurrency primitive that allows multiple tasks to run cooperatively within a single thread. OpenSwoole uses coroutines to process multiple IMAP accounts in parallel without the overhead of OS-level threads.
mbsync (isync)
A command-line tool that synchronizes IMAP mailboxes to a local Maildir. Bundled with imapfilter in the Cybolic docker-imapfilter-isync image for users who need both filtering and local sync.

FAQ

What is the difference between imapfilter and Sieve?

imapfilter is a client-side IMAP filtering tool that connects to any IMAP server from an external machine to process existing messages in mailboxes. Sieve is a server-side filtering language that runs inside the mail server at delivery time — before the message even reaches your inbox.

Sieve is faster and more efficient because it processes mail during delivery with zero polling delay, but it only works if you control the mail server or your provider offers Sieve support (some do, like Mailbox.org and Migadu). imapfilter works with literally any IMAP provider but runs on a polling interval. For self-hosted Dovecot setups, use Sieve. For hosted email accounts, use imapfilter.

Do I need to know Lua to use imapfilter?

Basic imapfilter rules — moving messages from a specific sender, filtering by subject keyword, marking mail as read — require very little Lua knowledge. The config format is mostly assignments and simple method calls, well-documented with plenty of examples in the official samples directory.

Complex rules with regex, multi-condition logic, or custom functions will require more Lua familiarity. If you’d rather avoid Lua entirely, consider fdm for declarative config syntax or imap-thingy for Python-based filtering.

Can I use imapfilter with Gmail?

Yes, but Gmail requires OAuth2 authentication or an app-specific password for IMAP access — regular password login is disabled by default. imapfilter supports OAuth2 natively, and the official extend.lua sample file includes a complete OAuth2 flow.

Alternatively, generate an app-specific password in your Google Account settings under Security and then 2-Step Verification and then App passwords. Once authenticated, imapfilter works with imap.gmail.com on port 993 with TLS. Keep in mind that Gmail uses labels rather than true folders, so moving a message to a label via IMAP only adds that label without removing it from the inbox.

How do I keep my email passwords secure with Docker imapfilter?

Several approaches, from most to least secure: use Docker secrets in Swarm mode; mount a config file with restricted permissions (chmod 600) and a dedicated user ID; use environment variables passed at container runtime.

With ntnn/docker-imapfilter, store your config in a private git repository and authenticate via an access token — no credentials on disk at all. The critical rule: never bake credentials into the Docker image itself. Always pass them at runtime. Use app-specific passwords rather than your account’s main password whenever your email provider supports them.

Should I use cron mode or daemon mode for imapfilter?

Daemon mode is more efficient for frequent checks — it keeps IMAP connections open between cycles, avoiding reconnection overhead. It uses imapfilter’s become_daemon() function or the IMAPFILTER_DAEMON=yes flag in ntnn/docker-imapfilter.

Cron mode is simpler to reason about. Each run is a clean slate, and if imapfilter crashes, the next tick picks it back up. For most setups, cron mode with a 5 to 15 minute interval is perfectly adequate and easier to debug. Use daemon mode if you need sub-minute checking or are on resource-constrained hardware where reconnection overhead actually matters.

Can imapfilter move mail between different email accounts on different servers?

Yes — this is one of imapfilter’s most powerful features. Define multiple IMAP account objects in your Lua config, each pointing to a different server. Select messages from one account and move or copy them to a mailbox on a completely different account.

You could pull newsletters from Gmail and move them to Fastmail, or aggregate mail from multiple accounts into a single archive. Messages transfer through the machine running imapfilter, so available bandwidth matters if you’re moving large attachments between providers.

Is imapfilter resource-heavy? Can I run it on a Raspberry Pi?

imapfilter is extremely lightweight. The binary is roughly 150KB, the Lua runtime adds minimal overhead, and memory usage is typically under 10MB. It runs comfortably on a Raspberry Pi Zero alongside other services. The resource bottleneck is usually the IMAP server’s response time and the number of messages per run, not imapfilter itself.

If you’re scanning large mailboxes frequently, limit the scan to recent messages using is_recent() or is_new() rather than select_all(). The sandipb Docker image is built on Alpine and has a particularly small footprint — ideal for ARM-based single-board computers.

How does imapfilter-llm-sort handle API costs and privacy?

The SQLite classification cache is the primary cost-control — once a message is classified, repeat encounters with the same Message-ID skip the API entirely. Temperature is locked at zero for deterministic results, so reclassification of the same content always yields the same answer.

For privacy, run the classifier against a local LLM via Ollama or LM Studio — no email data leaves your network and there are zero API costs. On cloud APIs, only message headers and a truncated body preview are sent, not full bodies or attachments. The default lookback window is one day, so only recent mail is classified.

What happens to mail that doesn’t match any filter rule?

With imapfilter, unmatched messages stay where they are — nothing happens to them. Your Lua config explicitly selects messages based on conditions, and only selected messages get actions applied. This is safe by design.

The imapfilter-llm-sort module is similarly conservative — if the LLM returns an unrecognized category name or an error, the message stays in the inbox rather than being misfiled. Always test new rules with imapfilter’s dry-run mode (the -n flag, or IMAPFILTER_DRY_RUN=yes in the sandipb image) before letting them run against your actual mailbox.

Can I combine multiple Docker imapfilter images or modules?

The Docker images are designed to run independently — one image with your config, not multiple. However, you can use imapfilter modules like snoozebox or imapfilter-llm-sort inside any Docker image by including the module Lua files in your mounted config directory and requiring them from your main config.lua.

Copy snoozebox.lua next to your config, add require(’snoozebox‘), and call the functions — it just works. You can combine multiple modules in the same config as long as their folder structures and function names don’t conflict.

Why would I build my own IMAP filter daemon instead of using imapfilter?

imapfilter is excellent, but it has two constraints that might push you toward a custom solution like the PHP and OpenSwoole setup described in this guide. First, the configuration is Lua code in a text file — there’s no web interface, no database backend, and no multi-user rule management. If you need non-technical users to manage filters through a browser, you’re building a frontend either way.

Second, if your filtering logic needs to query external databases, call internal APIs, or integrate with existing PHP business logic, writing Lua extensions for imapfilter is more work than building a native PHP daemon where the database connections and libraries are already available. For most individual users, imapfilter in Docker is the right call. For custom business workflows with a web UI, rolling your own makes more sense.

Let’s Talk!

Looking for a reliable partner to bring your project to the next level? Whether it’s development, design, security, or ongoing support—I’d love to chat and see how I can help.

Get in touch,
and let’s create something amazing together!

RELATED POSTS

Markdown is perfect right up until a second person touches it. On your own, a folder of .md files is the best documentation system ever invented. Add four colleagues and suddenly you’ve got three different heading styles, a README that links to a domain that expired in 2023, and Steve, who writes every sentence in […]

The short version: you do not need to pay for icons. Three permissively licensed sets cover nearly every project I touch — Tabler Icons (6,100+ general icons, MIT), Phosphor Icons (a huge family in six weights, MIT), and Lucide (1,808 minimal stroke icons, ISC). Need something specific that is not in those three? SVG Repo […]

Live streaming today means signing up for Twitch, YouTube Live, or another Big Tech platform. You get an audience, sure, but you also get ads you cannot control, algorithmic recommendations pushing viewers toward competing streams, rules that change overnight, and a chat system that ties your community to someone else’s database. For a hobbyist streamer, […]

Alexander

I am a full-stack developer. My expertise include:

  • Server, Network and Hosting Environments
  • Data Modeling / Import / Export
  • Business Logic
  • API Layer / Action layer / MVC
  • User Interfaces
  • User Experience
  • Understand what the customer and the business needs


I have a deep passion for programming, design, and server architecture—each of these fuels my creativity, and I wouldn’t feel complete without them.

With a broad range of interests, I’m always exploring new technologies and expanding my knowledge wherever needed. The tech world evolves rapidly, and I love staying ahead by embracing the latest innovations.

Beyond technology, I value peace and surround myself with like-minded individuals.

I firmly believe in the principle: Help others, and help will find its way back to you when you need it.