There is no single fix. A honeypot plus a timing check stops most automated submissions for free and with no friction. Cloudflare Turnstile handles the rest of the bots invisibly. None of it stops a human typing an SEO pitch, which is why server-side filtering on content and reputation is the layer most sites are missing.
Start here
Before adding anything, work out what you are actually receiving, because the methods below do not all solve the same problem.
| What you are getting | What it is | What will help |
|---|---|---|
| Gibberish text, random links | Automated, low effort | Honeypot, timing check |
| Identical submissions repeating | Automated, scripted | Rate limiting, timing check |
| SEO or web design pitches, written properly | A human | Content filtering, blocklists |
| Plausible enquiries that never answer | Click farm or fake lead | Reputation, validation, ad-side fixes |
| Foreign-language enquiries you cannot serve | Mixed | Geographic rules, content filtering |
Adding a captcha to fight human-typed SEO pitches is the most common wasted afternoon in this category.
The methods
Honeypot
A hidden field that a real visitor never sees and a bot fills in because it fills in everything. If it comes back with a value, the submission is automated.
Free, invisible, works anywhere. It stops basic automated submissions and it is the highest return per minute of setup of anything on this list. Capable bots recognise and skip it, so it should never be your only protection on a form that gets real traffic.
One thing to watch: if you later remove a honeypot plugin, remove its form tag too, or the tag can become visible to visitors.
Submission timing
A timestamp set server-side when the page loads. If the submission arrives faster than a person could realistically type, reject it.
Free, invisible, and effective against scripts, which submit instantly. No help against anything driven by a real browser at human speed.
Cloudflare Turnstile
Cloudflare’s CAPTCHA alternative. It runs a client-side challenge in the background of the visitor’s browser and does not pause the request or interrupt the experience. The challenges include proof-of-work, proof-of-space and browser-quirk detection, which is how it tunes difficulty per request without showing a puzzle.
Three modes: Managed, which decides whether to show a checkbox based on visitor risk and is the recommended default; Non-interactive, where the visitor sees a widget but never interacts; and Invisible, where the widget is hidden entirely. It is WCAG 2.2 AA compliant and can be embedded on any site without routing traffic through Cloudflare’s CDN.
Two practical notes. Tokens must be validated server-side via Siteverify, so dropping the widget on the page is only half the job, and using Invisible mode requires referencing Cloudflare’s Turnstile Privacy Addendum in your own privacy policy.
Google reCAPTCHA v3
Returns a score from 0.0 to 1.0 for each request, and you decide what to reject. Google’s documented starting threshold is 0.5, described as a default to tune away from rather than a target.
The mistake almost everyone makes is treating it as installed and done. reCAPTCHA learns from real traffic, so scores in staging or immediately after install differ from production, and Google’s own advice is to run it without taking action first and set thresholds by looking at your traffic in the admin console. It also supports named actions, which give a per-action breakdown for your top ten actions, and thresholds should be set per action rather than globally.
Even configured well, it answers one question: whether this session looks automated. A person hand-typing a pitch scores fine.
hCaptcha
Similar in shape to reCAPTCHA, with a privacy-focused position and no data going to Google. Same fundamental limitation.
Rate limiting
Caps how many submissions one IP can send in a window. A published practical limit is 5 per hour and 20 per day for a contact form.
Stops floods and repeated abuse from a single source. Set it too tight and you block offices, mobile networks and anyone else sharing an IP, which is a real cost on B2B forms.
Server-side filtering
The submission is sent to a service after the visitor presses send, and the service returns a verdict based on the message text, the sender’s address and IP reputation. Akismet, CleanTalk and OOPSpam all work this way, as do the services built into several form platforms.
Because it runs after submit, there is no puzzle and nothing on the page for a bot to reverse-engineer. It is the only method on this list that can catch spam written by a human, because it looks at what was actually said.
The trade-off is false positives. A filter that silently rejects can turn away real customers, and you will never know. What happens to a flagged submission matters more than the accuracy claim.
Blocklists and keyword filters
IP and email blacklists like StopForumSpam, plus your own list of phrases. Cheap, and useful against the repetitive stuff. They only know what is already known, so they trail new patterns rather than catching them.
Blocking free email domains
Rejects Gmail, Outlook and similar outright. Right for B2B, wrong for anyone selling to consumers, and the reason is worth reading before you switch it on: blocking free email addresses, and when not to.
Compared
| Method | Blocks | Visitor friction | Effort | Cost |
|---|---|---|---|---|
| Honeypot | Basic bots | None | Minutes | Free |
| Timing check | Scripts | None | Minutes | Free |
| Turnstile | Most bots | None to minimal | Under an hour | Free tier |
| reCAPTCHA v3 | Most bots | None visible | An hour, plus tuning | Free tier |
| reCAPTCHA v2 | Most bots | High | Minutes | Free tier |
| Rate limiting | Floods | None, unless too tight | Under an hour | Free to low |
| Server-side filtering | Bots and human spam | None | Minutes to configure | Usually paid |
| Blocklists | Known offenders | None | Under an hour | Free to low |
| Free-domain blocking | A category of junk, and real customers | None visible | Minutes | Free |
Work out your own answer
Every guide in this category lists the methods and leaves you to self-diagnose. Here is the routing instead. Start at the top and stop when you reach an instruction.
Have you added a honeypot and a timing check?
No, and you have not tried anything else either. Add both. They are free, take minutes, need no account and are invisible to visitors. On a low-traffic site this is frequently the entire fix, and you should not spend money before trying it.
No, but you already have a captcha. Add them anyway. A captcha is the expensive layer and you have skipped both free ones.
Yes. Continue.
Is the junk still arriving, and does it read like a machine wrote it?
Gibberish, random links, nonsense names, identical repeats. Add Cloudflare Turnstile in Managed mode, and validate the token server-side. Rendering the widget without checking the token is the most common half-implementation there is.
Nothing is arriving any more. Stop. You are done, and you do not need a captcha.
Is what arrives written properly, by a person?
SEO pitches, web design offers, plausible sentences. No challenge will help, because a captcha exists to let humans through and that is what sent it. You need something reading the message text and the sender’s reputation. That is server-side filtering, and if your form tool does not offer it, that is the constraint rather than your configuration.
Do the enquiries look real but never answer the phone?
That is not a form problem. It is a traffic problem, and it usually starts with a campaign change. Check Search Partners, location targeting and negatives before touching your form at all. Why am I getting fake leads covers the diagnosis.
Are you blocking submissions and unsure what you lost?
Whatever filter you use, find out what happens to something it flags by mistake. A tool that rejects silently can turn away a customer and leave no record anywhere. Held and reviewable is a different product from silently dropped, even where the detection is identical.
When the form system is the problem
If you have a honeypot, a timing check and a working captcha, and plausible junk still arrives every week, the issue is not a missing setting. Your form records what someone typed and nothing about who sent it, so every defence you add is guessing from one submission in isolation.
Lead Source answers that differently, by being the form rather than a layer in front of one: the checks sit in the form itself, so most junk never becomes a submission. That is a switch rather than an addition, and it is only worth it if the junk is costing you more than the move. See how form spam protection works.