Getting Started with Rate Limiting in Express for Node.js | How to Implement Rate Limiting in Express for Node.js

Getting Started with Rate Limiting in Express for Node.js | How to Implement Rate Limiting in Express for Node.js

What Is Rate Limiting?

Rate limiting is a fundamental mechanism for controlling the number of requests a client can make to a server in a given time frame. In a world where more than 30% of web traffic comes from malicious bots, that proactive strategy is critical to protect servers from abuse. In this tutorial you'll learn how to implement it in Express.

Specifically, there are two approaches to rate limiting:

  • Blocking incoming requests: When a client exceeds the defined limits, deny its additional requests.

  • Slowing down requests: Introduce a delay for requests beyond the limits, making the caller wait longer and longer for a response.

Why You Need API Rate Limiting in Node.js?

Implementing API rate limiting is crucial for maintaining stability, security, and fair usage of your Node.js application. In order to controlling the rate at which requests are processed helps enforce usage limits, prevents server overloads, and safeguards against malicious attacks.

Prerequisites

To follow this tutorial, you need a Node.js 20+ application. For example, the following basic Express server will be enough for this tutorial:

import express from 'express'
const app = express();

const PORT = 3000;

app.get('/api/hello', (req, res) => {
  res.status(200).send("Hello");
)}

app.listen(PORT, () => {
 console.log(`Application is running on ${PORT}`);
)}

This exposes a single /api/hello endpoint that returns ”Hello, World!”

What is express-rate-limit ?

This package use to limit repeated requests to public APIs and/or endpoints such as password reset.

Getting Started

Add the express-rate-limit npm package to your project's dependencies with:

npm install express-rate-limit

Implement the Rate Limiting Blocking Logic in Node.js

Create a new file rateLimit.js and import it from package so that you can use like the following code.

import rateLimit from "express-rate-limit";

export const rateLimiter = rateLimit({
    windowMs:  30 * 60 * 1000, // 30 minutes 
    max: 100, // limit each IP to 100 requests per windowMs
    message: "Too many requests from this IP, please try again after 30 minutes",
    standardHeaders: true,
    legacyHeaders: false,
    statusCode: 429
});

Note that rateLimit accepts an options object and returns the rate limiting middleware. The options used in the example above are:

  • windowMs: The time frame where requests are checked for rate limiting. The default value is 60000 (1 minute).

  • max: The maximum number of connections to allow during the windowMs time span. By default, it's 30.

  • standardHeaders: To enable support for the RateLimit headers recommended by the IETF. The default value is false.

  • legacyHeaders: To send the legacy rate limit X-RateLimit-* headers in the error responses. The value is true by default.

  • message: The response body to return when a request is rate limited. The default message is “Too many requests, please try again later.”

  • statusCode: The HTTP status code to set in the rate limiting error responses. The default value is 429.

How to use in application?

If you want to apply this throught the endpoints then check the following code

import express from 'express'
const app = express();
import { rateLimiter } from "./rateLimiter";
const PORT = 3000;

app.use(rateLimiter);  

app.get('/api/hello', (req, res) => {
  res.status(200).send("Hello");
)}

app.get('/api/namaste', (req, res) => {
  res.status(200).send("namaste");
)}

// Your can have more routes

app.listen(PORT, () => {
 console.log(`Application is running on ${PORT}`);
)}

To protect only a certain endpoint, pass limiter as a parameter in the endpoint definition: In the following example we have protected the /api/hello endpoint.

import express from 'express'
const app = express();
import { rateLimiter } from "./rateLimiter";
const PORT = 3000;

// protected the /api/hello endpoint.
app.get('/api/hello', rateLimiter, (req, res) => {
  res.status(200).send("Hello");
)}

app.get('/api/namaste', (req, res) => {
  res.status(200).send("namaste");
)}

app.listen(PORT, () => {
 console.log(`Application is running on ${PORT}`);
)}

If you want to learn this with using express-slow-down package then comment, like and follow me.

Thanks for reading!

Did you find this article valuable?

Support Shivam Sharma by becoming a sponsor. Any amount is appreciated!