🚦
Lesson 3 of 4 · Rate Limiting
The bouncer at the door
Count requests per user. Block when they go too fast. Auto-reset when the window expires.
🔴 The problem without rate limiting

A single bot can send thousands of login attempts per minute — trying stolen password lists against your users. Or a poorly written client can accidentally DDoS your own API. Without a gate, there's nothing to stop it.

✅ Request allowed
Requests used this window 1 / 5
1
requests used
4
remaining
30s
until reset

Make another request → Keep clicking until you hit the limit and see what gets blocked.

💻 What Redis did on this request
redis> INCR demo:ratelimit:<your-ip>
→ 1 ← total requests in this window
Atomically increments the counter for your IP address.
This was the first request — we also set the expiry timer:
redis> EXPIRE demo:ratelimit:<your-ip> 30
→ 1 ← timer set (only called on first request in a window)
We only call EXPIRE once — on the first request. This starts the 30-second window.
When the timer runs out, Redis deletes the key. The next request starts a fresh window.
💡 The clever trick — EXPIRE does the cleanup
1
First request: INCR + EXPIRE

Increment the counter, then set a timer. The timer only runs once — on the first request of each window.

2
Subsequent requests: INCR only

Check if the counter is over the limit. No need to reset anything — the timer is already running.

3
Window ends: Redis deletes the key automatically

No cron job. No scheduled cleanup. Redis just deletes the key when the timer expires. The next request starts a fresh window at count = 1.

🌍 Where you've seen this

GitHub API allows 5,000 requests/hour per token. Twilio rate-limits SMS sending to prevent abuse. Banks limit login attempts to prevent brute-force attacks. Stripe uses it per API key to prevent runaway billing.