Rate Limiting in JavaScript (Node.js): A Complete Guide to the express-rate-limit Library

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Rate Limiting in JavaScript (Node.js): Protecting Your API with express-rate-limit

In modern web development, protecting server applications from excessive load and malicious attacks is a critical task. One of the most effective protection mechanisms is rate limiting. This approach allows you to control the number of requests a client (IP address, user, or session) can send to the server within a specific time period. In the Node.js and Express ecosystem, the most popular and reliable library for implementing rate limiting is express-rate-limit.



What is rate limiting and why is it needed?

Rate limiting is a technique used to manage network traffic. It prevents abuse of server resources by protecting against:

  • DoS/DDoS attacks — mass requests aimed at taking the server offline.
  • Brute-force attacks — guessing passwords or access tokens.
  • Web scraping — automated data collection from a website.
  • Excessive API usage — when one client consumes more resources than allowed.

Without rate limiting, your application can become vulnerable and unstable, especially as your user base grows.



The express-rate-limit Library

express-rate-limit is a middleware for Express.js that provides a simple and flexible way to limit requests. It integrates into the request processing chain and automatically tracks the number of requests from each client. The library supports various stores (in-memory, Redis, MongoDB, and others), making it scalable for distributed systems.



Installation

To get started, install the library via npm:

npm install express-rate-limit


Basic Usage

The simplest example is limiting all application routes to 100 requests per hour from a single IP address:

const rateLimit = require('express-rate-limit');const express = require('express');const app = express();

// Create a limiterconst limiter = rateLimit({ windowMs: 60 * 60 * 1000, // 1 hour max: 100, // maximum 100 requests message: 'Too many requests from your IP. Please try again later.', standardHeaders: true, // Return standard RateLimit-* headers legacyHeaders: false, // Disable X-RateLimit-* headers});

// Apply to all routesapp.use(limiter);

app.get('/', (req, res) => { res.send('Home page');});

app.listen(3000, () => { console.log('Server running on port 3000');});


Configuration for Different Routes

Often, different endpoints require different limits. For example, a login route can have a stricter limit:

const rateLimit = require('express-rate-limit');

// Strict limit for /api/loginconst loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5, // 5 login attempts message: { error: 'Too many login attempts. Try again in 15 minutes.', retryAfter: 15 }, keyGenerator: (req) => { // Use IP + username for more precise blocking return req.ip + req.body.username; }});

app.post('/api/login', loginLimiter, (req, res) => { // Authentication logic res.send('Login successful');});

// Soft limit for public APIconst apiLimiter = rateLimit({ windowMs: 60 * 1000, // 1 minute max: 30, // 30 requests per minute message: 'API request limit exceeded.'});

app.use('/api/', apiLimiter);


Advanced Features

Custom Stores

By default, data is stored in the process memory. For production, we recommend

Recommendations