A honeypot is a hidden form field that bots fill out and humans do not. When the field contains data, the submission is rejected. A time trap records when the form was rendered and rejects submissions that arrive faster than any person could type, usually under three seconds. Together they stop most generic form spam with zero friction for real users. Studies report an 80 percent reduction in basic spam with honeypots alone, and over 99 percent of automated submissions blocked when combined with time-based checks. The checks must run on the server, because a check that only runs in JavaScript does nothing against a bot that posts the form directly.
The field that humans never see, and the name that gives it away
A honeypot exploits a simple difference between humans and bots: bots parse the HTML and fill out every field they find, while humans fill out only the fields they can see. Add an extra input to the form, hide it with CSS, and a bot that reads the HTML and fills in every input fills in this one too. The server checks the field, and if it has a value, the submission is spam. The visitor solves nothing and notices nothing, which is the whole point: the cheapest effective answer to form spam is layered, invisible, and free, with no external dependencies, no API costs, and no user friction.
The implementation details are what make it work or fail. Do not name the field honeypot or trap, because bots look for obvious names and skip them. Use a name that looks like a legitimate optional field, such as website or company, because bots expect forms to have those fields and will fill them. Hide the field off-screen with CSS, such as position absolute and left minus 9999 pixels, not display none, because some bots skip hidden inputs and a few check for display none specifically. Hide it from assistive technology as well, with aria-hidden and tabindex minus one, so a screen reader does not announce it and a keyboard user cannot tab into it. And check it on the server, because a honeypot checked only in JavaScript is a decoration.
Related reading on this site: Home and Bot Farms vs Device Farms: Two Different Infrastructures, Two Different Tells cover the neighbouring problems in more depth.
The clock that catches what the field misses
The second trap is time. A person needs a while to read and fill in a form. A script needs a fraction of a second. Record when the page loaded, check how long the submission took, and reject anything faster than a reasonable threshold. Humans take 5 to 30 seconds to fill a simple form with a name, email, and message. Bots submit in under 2 seconds. The Laravel Honeypot package uses a 1-second default threshold, and for complex forms 5 to 10 seconds is reasonable. A common implementation rejects submissions under 3 seconds, which is faster than any human reads and types.
The timestamp needs a signature. A plain hidden timestamp is trivially forged by a bot that sets it to an hour ago, so the render time should be signed with a server secret, which means the only way to get a valid token is to load the form, and loading the form costs the bot a real request and a real wait. Tokens should expire after about two hours, so a stale form escalates to a challenge instead of failing outright. And the response to a caught bot should pretend success, returning the same success page, so the bot learns nothing about what gave it away. A suspicious submission escalates to a challenge rather than discarding what might be a real person's message, because humans always need a path forward.
What honeypots cannot catch, and when to escalate
A honeypot is good at one thing: generic spam bots that crawl the web for forms and fill in every field they find. They send much of the junk that reaches contact forms and comment sections, and the honeypot catches them at no cost. It misses three kinds of attacker. Bots that run a real browser render the CSS, see that the field is off screen, and leave it alone. Bots written for your specific form will skip the honeypot and wait out the timer, because someone looked at the form once and saw the trap. And people, paid spammers and CAPTCHA farms, fill in what a person sees, and a person does not see the honeypot.
For most contact forms, newsletter signups, and comment boxes, honeypot plus time check provides adequate protection with zero friction, and the numbers support it: 80 percent of basic spam stopped by the honeypot alone, over 99 percent with the time check added. When bots keep coming after the honeypot is in place, or when the form protects something worth attacking, such as a login, a signup, or a checkout, escalate to a privacy-friendly challenge such as Cloudflare Turnstile, which does not track users the way Google's reCAPTCHA does. CAPTCHAs work but hurt the user experience, with about 30 percent of users abandoning forms with CAPTCHAs, according to Nielsen Norman Group. Stack the invisible, cheap signals first, and reserve anything a human can notice for the small share of borderline submissions.
Frequently asked questions
What is a honeypot field?
It is a hidden form field that bots fill out and humans do not. The field is hidden with CSS, humans never see it and leave it empty, and a bot that parses the HTML and fills every field fills it too. If the field has a value when the form is submitted, the server rejects it.
How fast is too fast for a form submission?
Humans take 5 to 30 seconds to fill a simple form. Bots submit in under 2 seconds. A common threshold rejects submissions under 3 seconds, and for complex forms 5 to 10 seconds is reasonable. The Laravel Honeypot package uses a 1-second default.
Why must a honeypot be checked on the server?
Because a check that only runs in JavaScript does nothing against a bot that posts the form directly, bypassing the page entirely. The field, the CSS that hides it, and the server-side check are all required.
What can a honeypot not stop?
Bots running a real browser that render the CSS and leave the hidden field alone, bots written specifically for your form, and human spammers from click farms or paid operators. For those, stack rate limiting and a privacy-friendly challenge on top of the honeypot.