Download this article as a PDF on the Codeflare Mobile App
Rate limiting restricts the number of requests a client can make within a specific time window.
429 Too Many Requests)Throttling controls the rate at which requests are processed, often by slowing them down rather than blocking them outright.
Learn on the Go. Download the Codeflare Mobile App from Google Play Store
| Feature | Rate Limiting | Throttling |
|---|---|---|
| Behavior | Blocks excess requests | Slows them down |
| Response | 429 error | Delayed response |
| Use case | Security & abuse control | Traffic shaping & smoothing |
Understanding these helps you design custom systems.
👉 Problem: A user can send many requests at the boundary
express-rate-limit (Most Common)npm install express-rate-limit const express = require('express');
const rateLimit = require('express-rate-limit');
const app = express();
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP
message: 'Too many requests, try again later',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api', limiter);
app.get('/api/data', (req, res) => {
res.send('API response');
});
app.listen(3000);
For distributed systems (multiple servers), in-memory limits won’t work.
Use Redis.
npm install rate-limiter-flexible ioredis
const { RateLimiterRedis } = require('rate-limiter-flexible');
const Redis = require('ioredis');
const redisClient = new Redis();
const rateLimiter = new RateLimiterRedis({
storeClient: redisClient,
points: 10, // 10 requests
duration: 1, // per second
});
const express = require('express');
const app = express();
app.use(async (req, res, next) => {
try {
await rateLimiter.consume(req.ip);
next();
} catch {
res.status(429).send('Too Many Requests');
}
});
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
app.use(async (req, res, next) => {
await delay(500); // delay each request
next();
});
class TokenBucket {
constructor(capacity, refillRate) {
this.capacity = capacity;
this.tokens = capacity;
this.refillRate = refillRate;
this.lastRefill = Date.now();
}
refill() {
const now = Date.now();
const diff = (now - this.lastRefill) / 1000;
this.tokens = Math.min(this.capacity, this.tokens + diff * this.refillRate);
this.lastRefill = now;
}
consume() {
this.refill();
if (this.tokens >= 1) {
this.tokens -= 1;
return true;
}
return false;
}
}
app.use('/login', strictLimiter);
app.use('/api', generalLimiter);
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 20 Return helpful errors:
{
"error": "Too many requests",
"retry_after": "60 seconds"
}
X-Forwarded-For)Backpressure is a flow-control mechanism that prevents a fast data producer from overwhelming a slower data…
JavaScript collections are data structures used to store, organize, retrieve, and manipulate groups of values. Choosing…
Context poisoning is a technique where an attacker deliberately places misleading, malicious, or irrelevant information into…
React makes building user interfaces easier, but certain errors appear repeatedly, especially when working with…
The C programming language is a foundational, general-purpose computer programming language created by Dennis Ritchie at Bell Labs in 1972. Originally developed to…
What Is Homebrew? Homebrew is a package manager for macOS and Linux that makes it easy to…