Mailbox search is built for finding one message you half-remember, not for working through an archive of tens of thousands. When you need every email where two terms appear near each other, or every subject line that matches a pattern, a single search box falls short. This post walks through the search operators mailin supports, explains how results are ranked, and shows why queries stay fast at million-message scale.
How to search an email archive: what gets indexed
When you import a mailbox, mailin builds a full-text index entirely on your device. The index covers the subject, the headers (senders and recipients) and the body of each message. Nothing is uploaded, and there is no account behind the search: the index lives in mailin's local data folder on your Mac, iPhone or iPad.
That matters for two reasons. First, you can search a sensitive archive with the network off. Second, the engine is a local SQLite full-text index (FTS5), which is what makes the operators below possible without a server.
Boolean operators: AND, OR, NOT
The basic building blocks are the three boolean operators. budget AND deadline returns messages containing both terms. invoice OR receipt returns messages containing either. contract NOT draft drops any message that mentions drafts.
You can combine them to narrow a large result set step by step. Start broad, look at what comes back, then add a NOT to exclude the noise: newsletters, automated notifications, a recurring thread that is not relevant. Because the index is local, each refinement is cheap, so iterating on a query is a normal way to work rather than something to avoid.
Wildcards, regex and proximity
A trailing asterisk matches any continuation of a term: invoic* finds invoice, invoices and invoicing in one query. This is the quickest way to cover word variants without typing each one.
For patterns rather than words, wrap a regular expression in slashes: /INV-[0-9]{4}/ matches reference numbers of a fixed shape, and /[A-Z]{2}[0-9]{6}/ matches something like an account identifier. Regex can return a lot, so it pays to combine it with a date range or a sender filter to keep the list reviewable.
Proximity search is the operator analysts reach for most. "budget" NEAR/5 "deadline" returns messages where the two words appear within five words of each other. A plain budget AND deadline would also match a long message that mentions the budget in paragraph one and a deadline in paragraph nine; the proximity form finds the sentence where someone actually connected the two.
What BM25 ranking means
Results are ordered by BM25 relevance. In plain terms, BM25 scores each message on how often your terms appear in it, adjusted for how long the message is and how rare the term is across the whole archive. A term that shows up in nearly every message (a company name in every signature, say) contributes little; a term that appears in only a handful of messages carries more weight. Short messages dense with your terms rank above long messages that mention them once.
The practical effect is that the messages at the top of the list are the ones most about your query, not just the newest ones that happen to contain the word. When you want chronology instead, the message list itself is ordered by date, and a date-range filter narrows it.
Why it stays fast: a year-sharded index
In mailin 2.0 the full-text index is split into one SQLite shard per year. A query bounded to a date range hits only the shard for that year; a query across the whole archive fans out to every shard and merges the results. Either way, mailin reports measured millisecond-level page latency at million-message scale.
Open database handles are capped at 20, with least-recently-used eviction driven by macOS and iOS memory-pressure signals, so an archive spanning many years does not mean many open files. If you are coming from v1, your existing index is migrated automatically with no rebuild. The same storage rewrite fixes the deep-scroll freeze described in the keyset pagination post.
Smart filters, AI smart filters and quick access
Operators handle content. Smart filters handle metadata: sender, domain, date range, folder, Gmail labels and whether a message has attachments. Combining a proximity query with a domain filter and a date range is usually the fastest route to a short, reviewable list.
If you would rather describe what you want, AI Smart Filters take a plain-English request and turn it into a filter. Because this runs through mailin's on-device AI engines, nothing leaves the device. AI features can produce inaccurate or incomplete results, so check the filter that was generated before relying on the list it produces. The free tier includes three AI smart-filter queries; the Personal tier removes the limit.
Three shortcuts round things out. The command palette (Cmd+Shift+P) lets you launch a search or a tool without leaving the keyboard. On the Mac, a menu-bar quick search is available. Optionally, mailin can index subjects and senders into Spotlight via CoreSpotlight; this is local only and can be switched off in Settings. Any query you build can be saved, and an optional weekly digest reports on your saved searches. The features overview lists everything the search layer supports.
FAQ
Does the full-text search cover attachment contents?
The full-text index covers subject, headers and body text. You can filter by whether a message has attachments, and the analytics views break attachments down by type and size.
Can I search across several imported files at once?
Yes. Everything you import goes into one archive, and a cross-archive query fans out across every year shard and merges the results into a single ranked list. Use the folder or label filters to narrow to one source when you need to.
Is search available in the free tier?
The free tier includes basic search and filters on up to 500 emails, with three AI assistant queries and three AI smart-filter queries. Advanced search is part of the Personal and Professional tiers; see the pricing section for details.