How many times in my career have I found that “simpler” really does mean “better”? I’m afraid it’s been too often. I came to this conclusion once again while working on improvements to my Polish blog. My recent blog improvements resulted in somewhat more casual post, which may offer you a few insights that will come in handy in your day-to-day programming work.
Context
After launching my blog, the comments section and contact form were obvious must-haves for me. I quickly noticed that any place on the blog where a user could type something became a target for bots. As a result, dozens, if not hundreds, of comments with links to online casinos, erectile dysfunction medications, and other sites offering products of dubious reputation ended up in my inbox and in my pending comments every day. A quick search showed that for my WordPress setup, combining Akismet with reCAPTCHA is a fairly effective solution.
Akismet is a spam detection tool. It doesn’t so much protect against spam as it does help determine whether something is spam. I hope I don’t need to introduce the CAPTCHA mechanism to anyone. However, just to go through the motions, the acronym CAPTCHA stands for “Completely Automated Public Turing test to tell Computers and Humans Apart.” The purpose of this mechanism is to prevent bots from performing actions on the website, such as filling out forms, clicking buttons, and so on. This is usually achieved through tasks that are simple for humans but difficult for computers to perform. These might include a simple puzzle, retyping text, or identifying objects in images. Sometimes CAPTCHA operates in the background, analyzing user behavior.
So I implemented both solutions, and the problem went away, but only temporarily. In early 2025, I received an email informing me that I needed to migrate reCAPTCHA to Google Cloud. Reading through the terms and conditions set off a few red flags for me:
I need to have a GCP account with billing set up and a credit card linked,
and the free tier covers only 10,000 requests per month.
In theory, I shouldn’t exceed the free limit, and even if I did, the cost for an additional 100,000 requests would be $8. That’s not a big deal, but if I exceeded the free limit every month for a year, that would amount to $96. Almost $100 for keeping the comments section on a personal blog. Protection against comments and messages advertising casinos and weight-loss patches isn’t something I’d want to pay potentially a hundred bucks a year for. In my case, there could only be one conclusion - I need to look for an alternative.
Another reason in favor of the switch is my aversion to corporate behemoths (I’m looking at you, Johnny Silverhand) and my long-standing desire to gradually phase out the Google ecosystem. While it will probably be hard for me to give up YouTube, Gmail, or Google Docs, reCAPTCHA is definitely not one of the services I couldn’t live without (Google Analytics - you’re next in line).
Attempt #1
My first attempt to solve the problem involved switching to Cloudflare Turnstile. Given my blog’s setup, I’m already tied to Cloudflare anyway, so using another service from their portfolio wasn’t a big deal. Plus, the service is free, and as everyone knows, free is a fair price. The switch itself took maybe a few minutes. Turnstile doesn’t present users with any puzzles or tasks to solve. In fact, you can even hide it completely. Cloudflare approaches the issue as follows:
Turnstile adapts the challenge outcome to the individual visitor or browser. First, we run a series of small non-interactive JavaScript challenges to gather signals about the visitor or browser environment.
These challenges include proof-of-work, proof-of-space, probing for web APIs, and various other challenges for detecting browser-quirks and human behavior. As a result, we can fine-tune the difficulty of the challenge to the specific request and avoid showing a visual or interactive puzzle to a user.
Imagine my surprise when, after a few weeks, I found several hundred comments awaiting approval in the “spam” folder. I started researching the issue, convinced that I had messed something up. However, after checking the statistics, it turned out that Cloudflare had classified about half of the traffic on my site as “likely bot.” This meant the solution was up and running and properly configured.
I checked the configuration options, but that didn’t help much. Not only was the most restrictive setting enabled, which sometimes requires checking an additional checkbox, but users also have to complete a challenge every single time (the pre-clearance option is disabled).
While researching the topic, I came across an interesting post on Reddit. It turns out I’m not the only one who’s noticed that something is off. I even managed to find a guide on how to effectively bypass the challenge set up by Turnstile. This definitely lowered my faith in the effectiveness of this service.
I also don’t assume the problem lies in Turnstile’s integration with the comments module. The same integration handles the contact form, and in that case, it works correctly. However, I can’t rule out the possibility that I did something wrong. As of now, I can’t say for sure whether I’m doing something wrong or if the problem actually lies with the service itself. If you have any thoughts on this, I’d love to hear more.
Attempt #2
My failure to successfully implement Turnstile led me to start looking for other options. My first thought was to look for another CAPTCHA alternative. After extensive research, however, I didn’t find anything I wanted to test in practice. I considered using ALTCHA, but ultimately abandoned the idea because it required deploying and maintaining my own backend. I also didn’t consider solutions based on math puzzles. I don’t want to force users to fill out unnecessary fields, especially since reCAPTCHA and Turnstile were already running in the background. I also considered going back to reCAPTCHA and waving the white flag in my attempt to break away from Google.
However, at that point, I decided to take a step back and rethink the actual problem. My problem isn’t the need to install a CAPTCHA solution, but the need to get rid of spam from bots. So I came up with the idea of simply automatically cleaning out the spam - say, every day. I ultimately rejected this idea after a comment from a real reader accidentally ended up in the spam folder.
I set out to do some more research, now facing a slightly different problem to solve, and that’s how I stumbled upon a solution that was brilliant in its simplicity. To work effectively, the bots used by spammers are usually generic. They rely on well-known mechanisms, tools, and interfaces. This means that any non-standard mechanism is unlikely to be handled correctly by most of them.
The solution, which has so far eliminated the spam problem, is absurdly simple. An invisible field was added to the comment form. For a comment submission request to be processed successfully, this field must be present. The second necessary condition is that this field must be empty. This solution allows us to detect two types of bot behavior:
In the query, include only the fields I know;
Check the available fields, enter values in all of them, and send a comment.
I’ve been testing this solution since November 2025, and not a single comment has ended up in the spam folder. At the same time, I know the commenting feature still works. Implementing this solution simply involves adding a simple action and a filter to the functions.php file.
add_action('comment_form', function () {
echo '<p style="display:none;"><label>Leave this field empty</label>
<input type="text" name="hp_comment" value=""></p>';
});
add_filter('preprocess_comment', function ($commentdata) {
if (!empty($_POST['hp_comment'])) {
wp_die('Spam!');
}
if (!isset($_POST['hp_comment'])) {
wp_die('Spam!');
}
return $commentdata;
});
Is this solution perfect? Definitely not! A quick check of the page’s HTML code immediately exposes our mechanism. I accept this risk because it requires more effort than just running an automated script. The past months have shown that the solution works. If someone really wants to, they’ll send me spam anyway. To draw an analogy - an electric fence was too expensive, so I decided to at least padlock the gate. And if someone really wants to, they’ll jump over it anyway.
Conclusions
I have two conclusions regarding the solution to this problem. The first concerns the question: Does simpler mean better? Often, the answer is yes. This is by no means universal advice. You need to have a sense of when you can take shortcuts and when doing so might backfire badly. However, in many cases, the simplest solution is sufficient. This is especially true when we’re talking about a non-critical area of our product or system. In the use case described, this is precisely the case.
The second conclusion is that sometimes it’s worth taking a step back and looking at the problem from a broader perspective. The solution may lie somewhere completely different from where we originally looked for it. It’s also possible that we’re trying to solve the wrong problem.

