In short
Without a limit, one script can try 10,000 passwords a minute or hammer your API until it falls over. Rate limiting says: slow down, come back later.
In a security context: capping request rates to blunt brute-force login attempts, credential stuffing, and denial-of-service style abuse against your API.

Think of it like this
The hostel mess roti rule
The mess bhaiya hands out rotis fast, but each student gets a few per round. Come back too soon and he points at the sand timer. Nobody goes hungry, and one hungry senior can't empty the whole tray. That's a rate limit.
Watch it happen
Login attempts from one IP, limit 5 per 15 minutes
1/5Each cell is a POST /login from the same IP inside one 15 minute window.
The big ideas
What you need to know
429 Too Many Requests
The standard reply when a client goes over the limit, often with a Retry-After header in seconds.
Pick the right key
Limit by IP for public routes, by user id or API key once logged in. Login routes deserve the strictest limits.
Share counters across servers
With three app servers, in-memory counters give each user three times the limit. Store counts in Redis instead.
Windows and buckets
Fixed windows are simple. Sliding windows and token buckets smooth out bursts at the edge of a window.
See it in code
Walk through the code
1import { rateLimit } from "express-rate-limit";2 3const loginLimiter = rateLimit({4 windowMs: 15 * 60 * 1000, // 15 minutes5 limit: 5, // 5 tries per IP per window6 standardHeaders: "draft-7",7 legacyHeaders: false,8});9 10app.post("/login", loginLimiter, loginHandler);1/3Five requests per IP every 15 minutes. Counters live in memory unless you plug in a store like Redis.
Behind a proxy like Nginx or a cloud load balancer, set app.set("trust proxy", 1) so the limiter sees the real client IP, not the proxy's.
Save yourself the pain
Common mistakes
Oops
Keeping counters in memory with several server instances.
Do this instead
Use a shared store like Redis so every instance sees the same count.
Oops
Forgetting trust proxy, so every user shares the load balancer's IP.
Do this instead
Set trust proxy correctly, or one busy user locks out everyone.
Your mission
Lock yourself out
Quick check
You run 4 instances of your API, each with an in-memory limit of 100 requests per minute. Roughly how many can one client get through?
Go deeper
- 1Add stricter rate limits specifically on auth endpoints (login, password reset).
- 2Learn account lockout vs rate limiting as complementary brute-force defenses.
- 3Monitor for rate-limit-triggering traffic patterns as an early abuse signal.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.