Resources / Spam filtering
How receiver-side spam filtering actually works
A spam filter is not one test with one threshold. It is a layered pipeline - connection and reputation checks, authentication, statistical content analysis, collaborative checksum networks, and rules engines - whose signals combine into a single decision. This page walks the whole chain so you can see where a legitimate message can go wrong.
Last checked: June 21, 2026
Most “how spam filters work” articles describe one technique - usually a keyword list or a single Bayesian score - and stop. Real inbound filtering is not one test. It is a pipeline of independent layers, each cheap-to-expensive, each catching a different kind of abuse, whose outputs are combined into a single accept/defer/reject decision. RFC 6647 states the design principle plainly: “Absent a perfect abuse-detection mechanism that incurs no cost, the current requirement is for an array of techniques to be used by each filtering system. They range in cost, effectiveness, and types of abuse techniques they target.”
This page is the map. It is written for senders: if you understand the chain a receiver runs, you understand where a perfectly legitimate message can still be misclassified - and which of those gates you actually control.
The 60-second version
- Filtering happens in stages, roughly cheapest-first: connection/reputation checks, then authentication, then content and collaborative analysis, then a scoring decision.
- Early stages can stop a message before content is ever read (a connection-level greylist or block), saving the receiver expensive CPU.
- Content stages produce scores, not verdicts. Engines like SpamAssassin and Rspamd add up many small signals into a running total.
- There is no universal score threshold. SpamAssassin defaults to tagging at 5.0; Rspamd uses a set of action levels - both are defaults that operators routinely tune. The number that matters is the one configured on the receiver in front of you, which you cannot see.
- A pass on any single layer does not guarantee delivery. Passing authentication, for example, proves who sent the message, not whether it is wanted.
- As a sender you mainly influence the early, deterministic layers (authentication, list hygiene, sending consistency). The content and collaborative layers are largely out of your hands - which is exactly why the deterministic ones must be clean.
The pipeline, stage by stage
Different products order and name these differently, but the shape is consistent. Rspamd, for example, documents an explicit four-stage pipeline - pre-filters, main filters (run in parallel), post-filters, then an action decision based on the cumulative score.
Stage 1 - Connection and reputation
Before a single byte of content arrives, the receiver already knows the connecting IP address and can look up its reputation: is it on a real-time blocklist (RBL/DNSBL), does it have valid forward/reverse DNS, has it sent here before? At this stage the receiver can also apply greylisting - returning a temporary 4xx “try again later” to unknown sources. Most spam-sending software does not retry after a temporary failure (“in spamming, volume counts for far more than reliability,” per RFC 6647), so legitimate senders that retry per RFC 5321 get through while a large class of bulk senders simply move on.
This stage is deliberately the cheapest. RFC 6647 notes that rejecting mail with a temporary 4xx “is very cheap in system resources… By stopping spam before it hits filtering processes, far fewer system resources are used,” and the delay also “gives real-time blackhole lists and similar lists the time to identify and flag the spam source.”
Stage 2 - Authentication
Next the receiver evaluates SPF, DKIM, and DMARC (and ARC for forwarded mail). These answer one question: was this domain used with authorization? Both SpamAssassin (via its SPF, DKIM, and DMARC plugins) and Rspamd (as a parallel main-filter stage with caching) run authentication as inputs to scoring - a DKIM pass or DMARC alignment lowers the spam score; a hard authentication failure raises it.
Authentication is the layer a sender controls most directly, and it is necessary but not sufficient. A DMARC pass proves the From domain was authorized; it asserts nothing about whether the content is wanted. Reputation, content, and engagement still decide placement.
Stage 3 - Content analysis (statistical / Bayesian)
Now the message body and headers are examined. The canonical content technique is statistical (Bayesian) filtering: the message is broken into tokens (words, header fragments, URL pieces), and each token carries a learned spam probability derived from the receiver’s own ham and spam corpora. Paul Graham’s 2002 “A Plan for Spam” popularized the approach; its central claim was that “the Achilles heel of the spammers is their message.” Crucially, Bayesian filters are trained per deployment - the same word can be spammy at one site and neutral at another - which is another reason there is no portable threshold.
Both major engines include a Bayesian classifier. SpamAssassin’s Bayes plugin needs at least 200 known spams and 200 known hams before it will score; Rspamd ships its own statistical classifier (incompatible with SpamAssassin’s database - it must be trained from scratch).
Stage 4 - Collaborative / near-duplicate signals
Statistical filters look at one message in isolation. Collaborative checksum networks look across the whole internet’s mail: DCC, Pyzor, and Vipul’s Razor each let many independent receivers report message fingerprints, so a message seen in bulk by thousands of recipients is flagged as bulk even if its content looks innocuous. DCC is explicit that it detects bulk, not spam: “only mail targets can say whether a message is solicited.” This is why these signals are designed to feed a score alongside whitelists, never to act as a standalone block - a wanted newsletter is also bulk.
Modern engines extend this with fuzzy hashing that survives per-recipient personalization. Rspamd’s fuzzy_check detects “similar (not just identical) messages… particularly effective against spam campaigns where the same message template is sent to many recipients with minor variations.”
Stage 5 - Rules, network tests, and the scoring decision
Finally the engine combines everything. SpamAssassin applies a large body of named rules (header tests, body tests, URI checks, network lookups, the Bayes result), each contributing a configured positive or negative score; the totals sum to the message’s spam score. Rspamd does the equivalent with named symbols and weights, then maps the cumulative score to one of four actions: pass, add header, greylist, or reject.
This is the step that defeats the “one keyword = spam” mental model. No single rule decides the outcome. A message can fire several mild spam-like rules and still be delivered because a strong authentication pass and good reputation pulled the total back down.
How scores combine (and why “negative points” exist)
The combining model is additive and signed. From SpamAssassin’s documentation: each rule that fires “contributes its configured score (positive = spam-like; negative = ham-like); the total is the message’s spam score.” That means a filter has ham-protective rules too - a valid DKIM signature, a known-good List-Id, a passing DMARC alignment can each subtract points. The final score is a tug-of-war, not a checklist.
Example of an additive score (illustrative - not a real ruleset)
+1.2 body looks like bulk marketing
+0.8 contains a shortened URL
+2.5 fuzzy-hash match against a known campaign
-1.5 valid aligned DKIM signature
-0.9 sender domain has local good reputation
----
+2.1 total -> below this receiver's tag threshold -> delivered
The numbers above are invented to show the mechanism. The real scores, and the real threshold they are compared against, live in the receiver’s configuration.
Why there is no single threshold
This is the most important takeaway for a sender, and the one most “spam score” tools get wrong.
- Defaults are not standards. SpamAssassin tags at 5.0 by default; that value is a starting point operators change. Rspamd’s action levels (greylist / add-header / reject) are likewise configurable defaults.
- Bayesian probabilities are local. A token’s spam probability is computed from the receiver’s own corpus. SpamAssassin’s own guidance is explicit: “Do not train Bayes on different mail streams or public spam corpora,” because that misleads the classifier. So the same message scores differently at every site.
- Collaborative counts are global and time-varying. A DCC bulk count or a fuzzy-hash weight rises as more recipients report; the same message scores higher an hour later.
- The decision is multi-layer. Even a high content score can be overridden by reputation, and a low one can still be deferred by a connection-level control.
Evaluation research reinforces this. The TREC Spam Track measures filters along a full ROC curve precisely because “there is a natural tension between ham and spam misclassification percentages. A filter may improve one at the expense of the other.” Every receiver picks its own operating point on that curve. There is no global pass/fail line to hit.
What a sender controls vs. what a receiver controls
| Layer | Who decides | What a sender can do |
|---|---|---|
| Connection / reputation | Receiver + your IP history | Send from consistent, warmed IPs; valid forward/reverse DNS; retry on 4xx |
| Authentication | You publish, receiver verifies | SPF, DKIM, DMARC aligned and complete - the layer you most directly own |
| Bayesian content | Receiver (local corpus) | Write like the legitimate mail your recipients already accept; no token-stuffing |
| Collaborative / fuzzy | Global recipients | Genuine consent; avoid look-alike bulk templates; honor unsubscribes |
| Scoring / threshold | Receiver config | Nothing directly - which is why every layer above must be clean |
The pattern is consistent: the layers you control are the early, deterministic ones. You cannot lower a stranger’s Bayes score or change their threshold. You can make sure that when your message reaches the scoring stage, it arrives with clean authentication, a consistent sending history, and genuine recipient consent, so the ham-protective signals fire and the spam-like ones do not.
Where to go deeper
Each layer on this page has its own reference:
- Statistical content scoring - see Bayesian spam filtering.
- Near-duplicate detection - see Fuzzy hashing and near-duplicate detection and DCC, Pyzor, and Razor.
- The rules engines - see SpamAssassin architecture and Rspamd architecture.
- Connection-level controls - see Greylisting, tarpitting, and rate controls.
- Staying on the right side of the filter - see False positives and ham protection.
- How any of this is measured - see Spam corpora and evaluation.
What this means for you, and what Egressif does
If you take one thing from this page: stop thinking in terms of “the spam score” and start thinking in terms of a chain of gates. The ones a sender owns - authentication, list hygiene, sending consistency, genuine consent - are early and deterministic. Get them right and you arrive at the scoring stage with the ham-protective signals already in your favor.
Egressif’s job is to keep those controllable layers clean and consistent so that when your mail reaches any receiver’s pipeline, nothing on the deterministic gates counts against it - aligned SPF/DKIM/DMARC, stable sending identity, and disciplined list handling. We cannot set another operator’s threshold or train their Bayesian database, and we will not pretend otherwise. What we can do is make sure your mail never gives those downstream layers an easy reason to add points.
Related references
- Bayesian and statistical spam filtering Statistical filters do not match keywords - they learn token probabilities from a receiver's own ham and spam, then combine the most telling tokens with Bayes' rule. This is the history, the math, and the operational caveats, ending with what it means for a legitimate sender.
- Fuzzy hashing and near-duplicate detection A single changed character defeats an exact hash, so bulk-mail detection needs hashing that tolerates variation. This explains the difference between exact and fuzzy hashing, how DCC and Rspamd implement near-duplicate detection, and why "bulk" is not the same as "spam."
- DCC, Pyzor, and Razor - collaborative checksum networks DCC, Pyzor, and Vipul's Razor let many receivers pool what they see, so a message sent in bulk is recognized as bulk even when each copy is personalized. Here is how each one works, how they differ, what they catch and miss, and the whitelist rule every legitimate bulk sender depends on.
- Apache SpamAssassin architecture SpamAssassin classifies mail by running many rules, each contributing a positive or negative score, and tagging messages whose total crosses a configurable threshold. Here is the scoring model, the plugin architecture, the network tests, the Bayes subsystem, and how training really works.
- Rspamd architecture Rspamd is an event-driven filtering framework that sits between the MTA and the internet, runs dozens of modules in parallel, sums named symbols into a score, and maps that score to an action. Here is the pipeline, the scoring and action model, fuzzy storage, and why it is fast.
- Greylisting, tarpitting, and rate controls Before any content is scored, receivers can slow or defer suspicious connections. Greylisting (standardized in RFC 6647) returns a temporary failure that legitimate senders retry and most spamware abandons. Here is the mechanism, the RFC's recommended implementation, the failure modes, and where tarpitting and rate limiting fit.
Tell us what you run today.
Domains, rough volume, current providers, and what hurts. You will get a straight answer on fit, and a real number, in one conversation.