egressif.

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.

CONNECTIONIP reputationAUTHSPF DKIM DMARCCONTENTBayesianCOLLABORATIVEDCC Pyzor RazorRULES ENGINESA / RspamdSCOREsigned sumACCEPTdeliverGREYLISTdefer 4xxJUNKspam folderREJECTrefuse
The receiver runs ordered, cheap-to-expensive layers; their signals sum into one score that maps to an action - never a single pass-or-fail test.

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

LayerWho decidesWhat a sender can do
Connection / reputationReceiver + your IP historySend from consistent, warmed IPs; valid forward/reverse DNS; retry on 4xx
AuthenticationYou publish, receiver verifiesSPF, DKIM, DMARC aligned and complete - the layer you most directly own
Bayesian contentReceiver (local corpus)Write like the legitimate mail your recipients already accept; no token-stuffing
Collaborative / fuzzyGlobal recipientsGenuine consent; avoid look-alike bulk templates; honor unsubscribes
Scoring / thresholdReceiver configNothing 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

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.

Talk to our team