Skip to content

Part 1 of 7 · Form spam filter series ~6 min read

A form spam filter on AWS for a few dollars a month

A contact form with no protection fills with rubbish, and the usual response is a CAPTCHA. That trades a visible cost on every genuine visitor against an invisible one on nobody, and the measurable drop in completions is frequently worse than the spam. This post walks through a small system that gets most of the benefit without asking your customers to identify traffic lights.

carving tool set
Photo by Philip Swinburn on Unsplash

Key takeaways

  • A missed lead costs far more than a spam message. Every threshold follows from that.
  • Cheap structural signals classify most submissions for free, before any model runs.
  • Three destinations: inbox, review queue, quarantine. Nothing is deleted.
  • No CAPTCHA. The visible cost falls on genuine visitors and the spam adapts anyway.
  • Designed on AWS for about $2 a month.

The whole system on one page

Before any code, here is the shape of what we are designing.

System: submissions scored cheaply, routed to one of three placesThree boxes across the top sit outside the AWS account. On the left, The form, with no CAPTCHA. In the middle, Signals: the honeypot, timing and structural evidence collected with the submission. On the right, Whoever answers: their inbox plus a review queue. Each connects by an arrow to the AWS account container below. Submissions flow down into the account. Structural evidence feeds in. Each submission goes back out to one of three places. Inside the AWS account are three components in a row. On the left, the Cheap scorer, using free signals, where most submissions are decided. In the middle, the Model band, used only for the ambiguous middle. On the right, the Router, sending to the inbox, the review queue or quarantine. A note at the bottom says nothing is deleted and the worst outcome for a real enquiry is a two-hour delay.AWS ACCOUNTThe formno CAPTCHASignalshoneypot, timing,structureWhoever answersinbox, plus a queueCheap scorerfree signals,most decided hereModel bandonly the ambiguousmiddleRouterinbox, review,quarantinesubmissionsstructuralevidenceone of threeplacesNothing is deleted. The worst outcome for a real enquiry is a two-hour delay.
Fig 1. Three things outside the account, three pieces inside it. The narrow model band in the middle is what keeps this both cheap and mostly deterministic.
  • App integration
  • Machine learning
  • Security & identity
  • Analytics
  • Front-end & mobile
  • People

The asymmetry

A small business’s contact form produces perhaps forty genuine enquiries a month and four hundred spam messages. The genuine ones are worth, on average, a meaningful fraction of a job. The spam costs about four seconds each to delete.

So the arithmetic is not close: deleting one real enquiry to save four hundred deletions is a bad trade by an enormous margin. Every threshold in this system is set from that, which is why the aggressive-looking decision — quarantine — still keeps everything and is searchable.

What runs on every submission (the inside)

  • The cheap scorer. Half a dozen structural signals that cost nothing: a honeypot field, how long the form was open, whether the message contains links, whether the fields were filled in a plausible order. Part 2 covers each and how much each is worth.
  • The model band. For the submissions the cheap signals cannot place, one call asking a narrow question: is this a person describing a need, or a template? Part 3 is about keeping that band small.
  • The router. Three destinations. Confident enquiry goes to the inbox immediately. Ambiguous goes to a review queue that somebody glances at twice a day. Confident spam goes to quarantine, retained and searchable.

One submission, end to end

One form submission from arrival to answer, in five stagesA horizontal row of five boxes joined by arrows. Submitted: with no CAPTCHA. Cheap signals: about eighty-five per cent are decided here. Model: the remaining fifteen per cent. Routed: to one of three places. Answered: or found later. A note says the second box is where the cost savings and most of the accuracy both come from.ONE SUBMISSION, END TO ENDSubmittedno CAPTCHACheap signals~85% decidedModelthe other 15%Routedone of three placesAnsweredor found laterThe second box is where the cost savings and most of the accuracy both come from.
Fig 2. The same system as one line. Deciding most submissions with free signals is what makes the model band affordable enough to be careful in.
  • App integration
  • Machine learning
  • Analytics
  • Front-end & mobile
  • People

In plain words

Somebody fills in the contact form asking about a bathroom. They took ninety seconds, left the hidden field empty, filled the fields in a sensible order, and wrote three sentences with no links in them. Every cheap signal says person, so it goes straight to the inbox with no model call and no delay.

A minute later a bot submits. It filled the hidden field, completed the form in under a second, and the message is two hundred words with four links about search engine optimisation services. Every cheap signal says bot, so it goes to quarantine, again without a model call.

The interesting one arrives on Tuesday: two lines, no links, a plausible name, a free-mail address, filled in eleven seconds. It might be somebody in a hurry on a phone or it might be a better bot. The cheap signals genuinely cannot say, so one model call asks whether it reads like somebody describing a specific need. It says probably, with middling confidence, so it goes to the review queue — and somebody glancing at that queue after lunch spends two seconds deciding it is a real job.

Design rules that shaped every decision

  • Never delete. Quarantine is retained and searchable, because “I filled in your form and heard nothing” is a conversation that happens.
  • No CAPTCHA. The cost falls entirely on genuine visitors and bots solve them anyway.
  • Cheap signals first, always. They are free, deterministic, and decide most submissions.
  • Keep the model band narrow. It is the expensive part and the least predictable part.
  • When uncertain, hold rather than drop. A two-hour delay is a much cheaper error than a lost lead.
  • Every decision is recorded with the signals behind it, so the thresholds can be tuned from evidence.

Why this shape

Spam filtering has a well-known failure mode: it works, everybody stops thinking about it, and six months later somebody discovers a folder of real enquiries. The reason is always the same — a filter confident enough to delete, and nobody watching the false positive rate because false positives are invisible by construction.

So this design refuses the deletion. Everything is kept, the ambiguous band goes to a human queue rather than a coin flip, and the quarantine is searchable by name and email so that the one conversation that reveals a false positive can actually be resolved. It is a slightly worse filter and a considerably better business decision.

The next four posts walk through each piece: the cheap signals, the model band, how a borderline reaches a person, and how the thresholds get tuned. One diagram per post, a cost breakdown, and an engineering reference at the end.

All posts