I've recommended rate limiting on login forms, signup forms, password resets, and public APIs throughout this year. Worth a specific follow-up: adding a rate limit to your configuration and confirming it actually works are two different steps, and it's common to do the first one and quietly skip the second.
Why a configured rate limit isn't automatically a working one
Rate limiting middleware has real configuration details that are easy to get subtly wrong: the wrong key being used to group attempts together, a limit applied to the wrong route entirely, a limit that resets far more generously than intended, or a limit that's active in one environment but not the one actually serving real traffic. Every one of these produces a rate limiter that exists in your code, looks correct on a quick read, and doesn't actually stop anything in practice.
How to actually verify it, in a few minutes
- Pick the endpoint you've rate-limited and send requests to it in a tight loop, quickly, more times than your configured limit allows, using a basic script or a request tool, not by clicking a button repeatedly by hand.
- Confirm that somewhere before your limit's threshold, you actually start getting blocked, a 429 response or an equivalent rejection, rather than every single request succeeding regardless of volume.
- Check that the limit is scoped the way you intended. If it's meant to be per-account, confirm two different accounts from the same IP aren't sharing one limit incorrectly. If it's meant to be per-IP, confirm switching your own testing IP or using a different network resets the count as expected.
- Test this against your actual deployed environment, not just locally, since rate limiting middleware sometimes behaves differently, or isn't even active, depending on environment configuration.
Why this specific gap is easy to miss
Adding rate-limiting middleware to a project is often a matter of installing a package and adding a few lines of configuration, which feels like a complete, done task the moment it's written. Whether that configuration actually produces the intended blocking behavior, under real conditions, at real volume, is a separate, empirical question that never gets asked unless someone deliberately tries to break past the limit on purpose, the same pattern as nearly everything else on this blog.
A rate limit you've configured but never tested gives you the comfort of having addressed the item on your checklist without necessarily having the actual protection that item was supposed to provide. The five minutes it takes to fire a burst of requests and watch what happens is the difference between believing you're protected and actually knowing it.