Rate Limiting in Express.js
Rate limiting is a security and performance technique used to control how many requests a client can make to your API within a specific time period. It helps protect your application from abuse, brute-force attacks, spam requests, and accidental overload.
In Express.js applications, one of the most common ways to implement rate limiting is by using the express-rate-limit package.
It is simple to configure and very useful for securing public APIs and authentication endpoints.
What is Rate Limiting?
Rate limiting is a technique that sets a maximum number of requests allowed from a user, IP address, or client within a defined time window.
For example, you may allow only 100 requests per 15 minutes from a single IP address. If the client exceeds that limit, the API will temporarily block further requests.
Why Rate Limiting is Important
- Protects APIs from abuse: Prevents excessive or malicious requests
- Improves security: Helps reduce brute-force login attempts
- Improves stability: Protects the server from overload
- Controls resource usage: Prevents one client from consuming too many resources
Common Use Cases of Rate Limiting
- Login and authentication endpoints
- Password reset APIs
- Public REST APIs
- Search APIs
- OTP verification requests
Installing express-rate-limit
To use rate limiting in an Express application, install the package:
Basic Rate Limiting Example
Here is a basic example using express-rate-limit:
In this example:
windowMsdefines the time window in millisecondsmaxdefines the maximum allowed requests per IP within that windowapp.use(limiter)applies the limiter to all routes
This means a client can make up to 100 requests every 15 minutes.
Custom Error Message
You can return a custom message when the rate limit is exceeded:
Applying Rate Limiting to Specific Routes
In many applications, you do not need the same limit for every route. For example, login APIs usually need stricter limits than general public routes.
In this example, the login route allows only 5 attempts every 15 minutes from the same client.
Why Rate Limiting is Important for Login APIs
Login endpoints are common targets for brute-force attacks where attackers try many password combinations. Rate limiting reduces this risk by restricting repeated attempts from the same client.
This is why rate limiting is often combined with bcrypt, JWT authentication, and account lockout logic.
HTTP Status Code Used
When the rate limit is exceeded, the server typically returns:
This clearly tells the client that the request limit has been exceeded.
Advanced Configuration Example
You can configure additional options for better control:
Here:
standardHeaders: truesends modern rate limit headerslegacyHeaders: falsedisables older header formatapp.use("/api", apiLimiter)applies the limiter only to API routes
Rate Limiting Strategies
1. Global Rate Limiting
Applies to the entire application. Good for general protection.
2. Route-Specific Rate Limiting
Applies stricter or looser limits to certain routes like login, OTP, or search.
3. User-Based Rate Limiting
Limits requests based on authenticated user identity instead of only IP address.
Rate Limiting vs Throttling
These terms are related, but not exactly the same:
| Concept | Meaning |
|---|---|
| Rate Limiting | Restricts total number of requests in a time window |
| Throttling | Controls the speed or frequency of requests more continuously |
Best Practices for Rate Limiting
- Use stricter limits on authentication routes
- Return clear error messages with status code 429
- Combine rate limiting with logging and monitoring
- Use Redis-backed stores for distributed applications
- Adjust limits based on route sensitivity and business needs
Using Redis with Rate Limiting
In multi-server or production environments, in-memory rate limiting may not be enough because each server instance tracks requests separately. In such cases, Redis is commonly used as a shared store for rate-limiting data.
This ensures that limits are enforced consistently across all application instances.
Common Mistakes
- Using the same limit for all routes
- Not protecting sensitive endpoints like login or OTP
- Setting limits too low and affecting real users
- Ignoring distributed setup requirements in production
- Not handling reverse proxy settings correctly
Real-World Use Cases
- Preventing login brute-force attempts
- Limiting OTP resend abuse
- Protecting search APIs from spam traffic
- Securing public APIs from excessive usage
Conclusion
Rate limiting is an essential part of API security and performance management. It protects your Express.js application from abuse, controls request traffic, and helps maintain server stability.
By using express-rate-limit, you can implement rate limiting quickly and effectively.
It becomes even more powerful when combined with Redis, authentication, and monitoring tools in production systems.

