All posts

March 10, 2026 · 4 min read

What a Missing Rate Limit Actually Costs, In Real Numbers

I've mentioned rate limiting more than once on this blog, usually as a line item on a longer checklist. I want to slow down on this one specifically and walk through what a missing rate limit actually enables, in concrete terms, because the advice tends to land as abstract caution rather than something with a real, calculable cost attached.

The simple math of an unlimited login form

A basic script can attempt a login request every few hundred milliseconds without much effort at all, easily a few hundred attempts per minute from a single machine, and that number scales further with almost no extra sophistication if the attempt runs from a handful of machines instead of one. Against a login form with no limit at all, that's tens of thousands of password guesses in an afternoon, aimed at a single known email address, using nothing more advanced than a list of commonly reused passwords from some other service's breach. No cleverness required. Just volume, against a door with no lock.

What that actually enables

If even a small fraction of your users reuse a password that's appeared in any other breach, and breach lists with billions of real credential pairs are freely available, an unlimited login form turns into a mechanical process: try every leaked password against every known email address, and collect whichever accounts happen to match. This is called credential stuffing, and it doesn't require finding a flaw in your app at all. It requires only that your login form doesn't stop someone from trying enough times.

What it costs on the API side, not just login

The same unlimited-attempts math applies to any endpoint, not just login. An unlimited signup endpoint can be used to generate thousands of fake accounts to hoard a referral bonus or exhaust a promo code. An unlimited AI-feature endpoint, if your app has one, can run up your own usage bill dramatically, since every call typically costs you real money whether or not the caller has any legitimate reason to be making it. An unlimited password-reset endpoint can be used to spam a real user's inbox repeatedly, an annoyance on its own and sometimes a setup for a different kind of attack.

Why this rarely gets prioritized until it's already happened

None of this shows up in normal testing, because normal testing involves a human clicking at human speed. The gap is invisible until something inhuman starts hitting the endpoint instead, at which point it's usually discovered by a spike in your hosting bill, a flood of fake accounts, or a wave of angry emails about repeated reset messages, rather than by a deliberate check beforehand.

The fix is still the same short one

A basic rate limit, a handful of attempts allowed per time window, per account or per IP, closes off nearly all of this in an afternoon of work, using a library your framework almost certainly already has. The math above isn't meant to be alarming for its own sake. It's meant to make the cost of skipping this specific, well-understood fix concrete enough that it stops feeling like optional polish.

Related reading

Harbova is a security service for apps built with AI tools. Start with a free scan, and if it finds something serious, we can fix it and prove it is closed.