Rate Limiter Service
Part of the Backend Developer Roadmap
In short
Rate limiting protects APIs from abuse, runaway scripts and surprise bills. Building it as a real service, shared across many servers, is a system design answer you can actually demo.
A standalone rate-limiting service other applications can call — practice for implementing a real system-design interview question as working, deployed code.

Think of it like this
The gatekeeper at a college fest
The hall holds only so many people per hour. The gatekeeper counts entries and, once the limit is hit, says "wait 10 minutes". If there are three gates, they share one count over walkie-talkies, or the limit means nothing.
Watch it happen
Request number 101 in a minute
GET /search
1/6A client sends its 101st request within the same minute.
The big ideas
What you need to know
Pick an algorithm
Fixed window is simplest. Sliding window is fairer at the edges. Token bucket allows short bursts.
Shared, atomic counters
Keep counts in Redis with INCR or a Lua script, so every server instance sees the same number.
Clear responses
Return 429 with Retry-After, plus headers telling clients their limit and how much is left.
Decide on failure mode
If Redis is down, do you allow everything (fail open) or block everything (fail closed)? Choose on purpose.
See it in code
Walk through the code
1import Redis from "ioredis";2const redis = new Redis(process.env.REDIS_URL!);3 4export async function allow(key: string, limit = 100, windowSec = 60) {5 const window = Math.floor(Date.now() / 1000 / windowSec);6 const redisKey = `rl:${key}:${window}`;7 8 const [[, count]] = (await redis9 .multi()10 .incr(redisKey)11 .expire(redisKey, windowSec)12 .exec()) as [Error | null, number][];13 14 return { allowed: count <= limit, remaining: Math.max(0, limit - count) };15}1/3Work out which minute we're in and build a key like rl:user:7:29481730.
A fixed-window limiter. Each minute gets its own key that deletes itself, so Redis memory stays small.
Save yourself the pain
Common mistakes
Oops
Keeping counters in each server's memory.
Do this instead
With 3 servers behind a load balancer, users get 3x the limit. Use a shared store like Redis.
Oops
Limiting only by IP address.
Do this instead
Many users share one IP on college Wi-Fi or mobile networks. Prefer user ID or API key, with IP as a fallback.
Your mission
Milestone 1: a shared limiter
Quick check
Your API runs on 4 servers, each with its own in-memory limit of 100 per minute. What's the real limit for a user?
Go deeper
- 1Implement at least two algorithms (token bucket and sliding window) and let callers choose.
- 2Make it usable as a shared service across multiple client applications via Redis.
- 3Add clear response headers (remaining requests, reset time) like real APIs do.
More projects 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.