Every captcha comparison you can find measures the same thing: how much spam gets through. That is the easy half of the question. The hard half — the one that costs money — is what happens to the real customer who gets blocked by accident. A contact form submission that never arrives does not generate a bounce, an error, or a support ticket. It simply does not exist, and nobody on your side ever knows it was there.

That is the angle we took for this comparison. We installed Must-Have Captcha on a test site, deliberately produced a false positive from a submission that any human would recognise as a genuine enquiry, and then tried to get that lead back. Then we looked at what Google reCAPTCHA offers for the same situation, and at what each option costs the visitors who never do anything wrong.

Two different places to make the decision

The two products are built on the same broad idea — score the visitor’s behaviour instead of asking them to solve a puzzle — but they run that logic in different places, and that difference drives almost everything else.

reCAPTCHA loads Google’s script on your page, collects signals in the browser, and sends a token to Google. Your server then calls Google’s API to exchange that token for a verdict (v2) or a score (v3). The decision is made on Google’s infrastructure, and the raw signals never touch your server.

Must-Have Captcha collects interaction signals with a small script of its own, stores them in a signed cookie on the visitor’s browser, and scores the request in PHP on your own server when the POST arrives. According to the plugin documentation, the cookie holds base64-encoded JSON with a SHA-256 signature tied to the user agent, and the score is compared against a threshold — 15 for Basic, 30 for Normal, 60 for Strict. If the score is below the threshold, the request is blocked with a 403 before WordPress processes it.

Must-Have Captcha 0.3.5Google reCAPTCHA (v2 / v3)
Where the decision is madeYour server, in PHPGoogle’s infrastructure
Third-party requests on your pagesNonegoogle.com and gstatic.com
SetupActivate; works with defaultsRegister the site, copy site key and secret key
Visitor frictionInvisible; no widgetv2: checkbox, sometimes an image challenge. v3: badge only
Blocked submissionsStored and reviewable in wp-adminNot stored; the submission is gone
Recovering a false positiveOne click (“Accept”)No built-in path; needs custom development
Per-URL / per-IP rulesBuilt in (Custom Rules)Score thresholds in your own code

The last two rows are the ones this article is about.

How we tested

All measurements below come from one WordPress install, so the numbers are comparable with each other. They are not benchmarks of your site, and a different threshold or a different visitor mix will produce different scores.

  • Environment: WordPress 7.1, PHP 8.3.30, Apache, no page cache, Must-Have Captcha 0.3.5.
  • Protection level: Normal — the shipped default, threshold 30.
  • Forms: Contact Form 7 6.1.7 with Flamingo storing the entries, and the stock WordPress comment form on a blog post. Two of the most ordinary things you can put on a WordPress site.
  • Submissions: sent with curl, each one carrying a signed interaction cookie built to represent a specific visitor profile (or no cookie at all, for the script-bot case), plus a matching user agent and client IP.
  • reCAPTCHA payload: measured by loading Google’s own public reCAPTCHA v2 demo page in a Chromium browser and recording every request to google.com and gstatic.com.

Before any of that, here is what the protected Contact Form 7 form looks like to a visitor. There is no checkbox, no badge, and nothing to click — the only sign the plugin is there is a 4.6 KB script in the page source.

A Contact Form 7 form protected by Must-Have Captcha with no captcha widget or checkbox visible
A stock Contact Form 7 form with Must-Have Captcha active. Nothing for the visitor to do.

And here is the settings screen. Three protection levels, a handful of toggles, and — relevant to the comparison — no fields for an API key or a secret.

Must-Have Captcha settings with Basic, Normal and Strict protection levels and no API keys to enter
Protection level, honeypot, log retention. No keys to register.

Six submissions, five blocks

We sent six requests: four spam-shaped ones, and two from profiles meant to represent real people. Here is what the plugin scored them.

SubmissionProfileScoreResult
Contact Form 7Bot with no JavaScript at all (no cookie)0Blocked
Contact Form 7Headless browser, form filled in 0.4 s, spam content−71Blocked
Contact Form 7Form filler that also filled the hidden honeypot field−1000Blocked
Contact Form 7Real enquiry from a phone, text pasted, 2.4 s on page13Blocked
Blog commentReal reader on a tablet, pasted comment, no typing signals20Blocked
Contact Form 7Real enquiry from a desktop, typed, 74 s on pageabove thresholdDelivered

The three spam cases behaved as you would hope. The honeypot is the bluntest of them: the plugin injects a hidden field into forms, and any submission that fills it in is scored −1000 immediately. A request that arrives with no interaction cookie at all — the signature of a script that never ran your JavaScript — scores 0, which sits below the threshold at every protection level, including Basic.

Must-Have Captcha Blocked Requests dashboard listing five blocked submissions with their trust scores
The Blocked Requests tab. Every blocked submission is listed with its URL, type, IP, score and time.

Meanwhile the visitor whose submission was blocked sees this, and nothing else:

The default Request Blocked page a visitor sees when a submission is blocked
The default blocked page. It can be replaced with any WordPress page from the settings.

The two that should not have been blocked

Look at rows four and five. Neither of those profiles is exotic. The contact form submission came from an iPhone, from someone who wrote the message somewhere else, pasted it in, and hit send within a few seconds. It scored 13 against a threshold of 30 — not because the content looked like spam, but because the session produced very little of what the scoring engine reads as human: no typing, no mouse movement, a short time on the page and several pastes.

This is the shape of a false positive that behaviour-based protection will always be capable of producing, no matter whose engine is doing the scoring. People paste. People arrive from a bookmark, fill in one field and leave. People use assistive technology that does not generate the mouse events a scoring model expects. Turn the protection up and you catch more spam and more of these; turn it down and you catch less of both. There is no threshold that makes the problem disappear.

Where the products differ is what is available to you afterwards. In Must-Have Captcha the blocked submission is still there, with everything the visitor sent:

Submission details of a blocked contact form entry in Must-Have Captcha with the Accept button and the full form data
The submission details view: score, device, IP, and the complete form data — a legitimate quote request that scored 13.

A human reading that screen needs about three seconds to decide it is a real enquiry from a dental practice asking for a quote. The question is what you can do about it.

Replaying a blocked submission

The Accept button at the top of that panel replays the request. We clicked it, confirmed the dialog, and the row disappeared from the list.

Must-Have Captcha blocked requests list after accepting a submission, with the row removed
After Accept: the total drops from 5 to 4 and the accepted request is removed from the log.

More usefully, the enquiry itself arrived. Contact Form 7 processed it exactly as it would have the first time, and the lead that was invisible sixty seconds earlier is now sitting in Flamingo’s inbox next to the submission that had passed normally:

The recovered Contact Form 7 lead in Flamingo Inbound Messages after replaying the blocked submission
Marina Alvarez was blocked with a score of 13. After the replay her enquiry is in the inbox like any other, tagged with the form it came from.

We repeated it with the blocked comment, and it behaved exactly the way a genuine comment would have: it went into the moderation queue rather than straight onto the post.

The replayed WordPress comment waiting in the comment moderation queue
The replayed comment lands in Pending, exactly as WordPress would have handled it the first time.

What “replay” actually does

This is worth understanding before you rely on it, because it is not a “mark as approved” flag. When a request is blocked, the plugin stores the POST body, the request headers and the cookies alongside the score. Accepting it makes your own server send that stored request back to the original URL with a one-time key, and the plugin rebuilds $_POST, the headers and the cookies from the stored copy — including the original Content-Type, which is what lets a REST-based form endpoint accept it — and sets an internal bypass flag so the captcha does not block it a second time. From that point WordPress runs the request normally: whatever plugin, form handler or hook would have processed it the first time processes it now. The stored copy is only deleted once the replay has actually gone through.

That design has three consequences worth knowing about.

  • Submissions containing sensitive data cannot be replayed. Fields matching patterns like password, card number, CVV or token are masked before storage, and the documentation states that a request whose data was masked is not replayable — the original values were never kept. In practice this means contact forms, registrations and enquiries are recoverable; a blocked login or checkout submission is not.
  • The replay comes from your server. Anything downstream that records the client IP will see the server’s own address rather than the visitor’s, because the request is genuinely re-sent from the site itself. The original IP is still visible in the blocked-request log.
  • It only works for submissions that were actually blocked. If a form endpoint is on your Custom Rules list as “Block & Ignore”, nothing is stored, and there is nothing to replay. That is the intended trade-off for high-volume endpoints you never want logged.
  • A replay that fails does not lose the submission. We tested this deliberately by deactivating the form plugin between the block and the replay: the endpoint answered 404, and instead of a success message the admin got “The request could not be replayed (the target endpoint answered with HTTP 404). It has been kept in the log so nothing is lost.” — with the row still in the list, ready to try again once the cause is fixed.

In our test the replay worked for both submission styles we threw at it: Contact Form 7’s REST endpoint, which posts multipart/form-data, and the stock WordPress comment form, which posts a classic form-encoded request. Both arrived intact.

What reCAPTCHA gives you for the same false positive

Nothing equivalent, and that is a consequence of the architecture rather than an oversight.

With reCAPTCHA v2, a visitor who fails the challenge never gets a valid token, so the form is never submitted. There is no request for your site to store, review or replay — the data stayed in the visitor’s browser and left with them when they closed the tab. Google’s admin console will tell you how many challenges were served and how many were solved; it will not tell you who gave up, and it cannot give you back what they were typing.

With reCAPTCHA v3 the picture is slightly better, because the form does reach your server together with a score between 0.0 and 1.0. What happens next is entirely your code’s decision. If your form plugin is configured to reject submissions below the threshold, the submission is discarded — the same outcome. If you build the alternative yourself, you can store low-score submissions in a review queue and process them manually later. That is a perfectly reasonable pattern, and if you have a developer on the project it is not a big piece of work. It is just work that you do, and maintain, rather than a feature you switch on.

The practical version of the difference: with Must-Have Captcha, reviewing false positives is a tab in wp-admin. With reCAPTCHA, it is a ticket in your backlog.

What each one costs the visitors who did nothing wrong

False positives are the expensive failure. Page weight is the everyday one, and it is easy to measure precisely.

We loaded the protected contact form and recorded every request the browser made. Must-Have Captcha added exactly one: its own captcha.js, 4,632 bytes uncompressed (about 2 KB gzipped), served from the site’s own domain. The page made no requests to any third-party host at all.

Then we loaded Google’s official reCAPTCHA v2 demo page and recorded every request to google.com and gstatic.com. There were 13 of them, covering seven distinct resources.

ResourceDecoded size
recaptcha__en.js779,653 bytes (≈320 KB gzipped over the wire)
styles__ltr.css82,980 bytes
api2/anchor (widget iframe)54,797 bytes
api2/bframe (challenge iframe)17,194 bytes
api.js (loader)1,548 bytes
logo + web worker2,330 bytes
Total, unique resources≈938 KB decoded, across 13 requests to two third-party hosts
Google reCAPTCHA v2 I am not a robot checkbox on Google official demo form
Google’s own reCAPTCHA v2 demo form — the page we measured.

Two caveats so the comparison stays honest. Those resources are cached aggressively and shared across every site that uses reCAPTCHA, so a returning visitor who has met reCAPTCHA elsewhere may pay very little of that cost. And reCAPTCHA v3 skips the challenge iframe, so its footprint is smaller than v2’s — though it still loads the same main script. What does not change is the number of hosts involved: one of these approaches keeps everything on your domain, and the other does not.

Friction, privacy and price

Friction. reCAPTCHA v2 asks the visitor to do something. Most of the time that is one click, but “most of the time” is doing real work in that sentence — visitors on VPNs, on shared IPs, or with strict privacy settings meet the image challenge far more often, and image challenges are exactly the point where people abandon forms. v3 removes the interaction and shows a badge instead. Must-Have Captcha shows nothing at all; the visitor’s first sign of it is the blocked page, if they ever see it.

Privacy. reCAPTCHA sends visitor signals to Google, which makes it a third-party data transfer you have to account for in your privacy policy and, in the EU, in your consent handling. Must-Have Captcha keeps the signals in a first-party cookie and scores them on your server, so there is no transfer to disclose — and if you run Must-Have Cookie, its cookie is registered as essential so protection keeps working before consent. The flip side is worth stating plainly: the blocked-request log stores the contents of blocked submissions, which is personal data sitting in your database. The Expiry setting (from one day to “keep forever”) is how you control that, and one week is a sensible default for most sites.

Price. reCAPTCHA Essentials is free up to 10,000 assessments per month, and Google’s pricing page notes that the free allowance is counted per organisation across all accounts and sites, not per site. Above that it is a flat $8 per month to 100,000 assessments, then $1 per 1,000. Must-Have Captcha is $6.99 per year for one site, $12.99 per year for five, or included in the Must-Have Pack at $59.99 per month with every other Must-Have plugin.

Must-Have CaptchareCAPTCHA
Entry price$6.99 / year, 1 siteFree to 10,000 assessments / month
Five sites$12.99 / yearFree allowance is shared across all of them
Higher volumeSame price$8 / month to 100k, then $1 per 1,000
Front-end payload measured1 request, 4.6 KB, same domain13 requests, ≈938 KB decoded, two Google hosts
Recovering a blocked leadBuilt inBuild it yourself (v3) or not possible (v2)

Where reCAPTCHA is still the stronger choice

A comparison that only points one way is not much use, so: there are real reasons to stay with Google.

  • Signal scale. Google sees traffic from an enormous share of the web, and cross-site reputation is a genuinely powerful signal that no self-hosted plugin can reproduce. Against a determined, well-resourced attacker that matters.
  • An escalation step. reCAPTCHA can present a challenge to a borderline visitor and let them prove themselves. Must-Have Captcha has one outcome for a low score: block, and rely on you reviewing the log afterwards. For a site where a blocked visitor would simply give up and never come back, being able to offer them a puzzle is a real advantage.
  • It is already integrated everywhere. Nearly every form plugin ships a reCAPTCHA field. If your stack is built around that, switching is a project rather than an afternoon.
  • Zero cost at low volume, if a shared 10,000-assessment allowance covers your whole portfolio.

Who should choose what

Choose Must-Have Captcha if your forms carry enquiries you cannot afford to lose quietly — quote requests, bookings, applications, B2B leads — or if you would rather not add a third-party data transfer to a site you are keeping GDPR-tidy. It also suits agencies managing several small sites, where a five-site licence costs less per year than an hour of support time spent explaining a missing enquiry.

Stay with reCAPTCHA if your forms are low-value and high-volume (newsletter sign-ups, comment forms on a large publisher site), if you are already under sustained targeted attack and want Google’s cross-site reputation data, or if you specifically want the option to challenge a suspicious visitor instead of blocking them outright.

Consider both. They are not mutually exclusive. Some sites put reCAPTCHA on the login and registration flows, where challenges are acceptable and replay is not possible anyway, and use a self-hosted scorer with a review log on the forms that carry revenue.

Frequently asked questions

Does replaying a blocked submission send the emails too?

Yes, as far as your form handler is concerned nothing is different. The request is re-sent to the original URL and processed by WordPress normally, so notification emails, entry storage and any hooks your form plugin fires all run at that point — just later than the visitor expected.

Can I replay a blocked login or checkout?

No, and that is deliberate. Passwords, card numbers and similar fields are masked before the request is stored, and a request whose data was masked is marked as not replayable because the original values no longer exist. For those flows the answer is a Custom Rule that relaxes protection on the endpoint, not a replay.

How long are blocked submissions kept?

It is a setting: one day, one week, one month, one year, or forever, cleaned up by a daily cron job. Since the log contains the contents of the blocked submissions, treat it like any other store of personal data and pick the shortest window that still gives you time to review.

Will a self-hosted captcha catch as much spam as Google?

For ordinary automated spam — the scripts and form fillers that make up the overwhelming majority of what hits a WordPress site — behavioural scoring plus a honeypot is very effective, and our test cases were all stopped comfortably below the threshold. For a targeted attack by someone who is specifically interested in your site, Google’s cross-site data is an advantage. Most sites are dealing with the first problem, not the second.

What happens if I set the protection level too high?

You block more real people — and, unlike with most captchas, you can see exactly who. That is arguably the most useful way to use the blocked-request log: run Strict for a week, read what got caught, and tune down (or add a Custom Rule for a specific URL) based on what you actually see rather than on guesswork.

Do I need to add anything to my forms?

No. There is no shortcode or field to place — the plugin validates POST requests site-wide once it is active, which is also why per-URL Custom Rules exist for endpoints that should be treated differently.

The takeaway

Both products will stop the spam that arrives at an ordinary WordPress site. Neither can promise it will never block a real person, because no behaviour-based system can — the profiles that trip it up are ordinary ones, and in our test a genuine quote request from a phone scored 13 against a threshold of 30.

What differs is the recovery path. One architecture makes the decision on someone else’s servers and leaves you with a number; the other makes it on yours, keeps the evidence, and gives you a button. If the forms you are protecting carry enquiries that are worth money, that button is the part of the comparison worth thinking hardest about — and the failure mode it addresses is precisely the one you would otherwise never find out about.

If you want to look closer: the Must-Have Captcha documentation covers the scoring signals, filters and Custom Rules in detail, and we have written separately about reviewing and recovering blocked submissions, when to use Custom Rules, setting the plugin up, and why behaviour-based protection beats puzzles. If losing form submissions is a recurring worry rather than a one-off, it is also worth reading how to monitor your forms so you find out when they break for other reasons too. Google’s own reCAPTCHA v3 documentation and its current pricing page are the right sources for the other side.