WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Node.js · Expert · question 73 of 100

How do you implement rate limiting in a Node.js application to prevent abuse and ensure fair usage?

📕 Buy this interview preparation book: 100 Node.js questions & answers — PDF + EPUB for $5

Implementing rate limiting in a Node.js application is essential to prevent abuse and ensure fair usage of the application resources. Rate limiting allows you to limit the number of requests any client or user can make to your server within a specific time period.

There are mainly two approaches to implement rate limiting, one is in-memory rate limiting, and the other is centralized, which often uses a data store like Redis.

I will explain both methods in brief and provide code examples.

**Method 1: In-memory rate limiting**

Implementing in-memory rate limiting can be done using middlewares in Express.js. In this approach, we will store the request count for each IP address in a JavaScript object.

Here’s an example of how to create a simple in-memory rate limiter middleware in an Express.js application.

1. First, install ‘Express‘ if you haven’t already:

$ npm install express

2. Create an ‘index.js‘ file, and paste the code below:

const express = require('express');
const app = express();

const rateLimitWindowInMs = 60 * 1000; // 1 minute
const maxRequestsPerWindow = 10;

const requestsForWindow = new Map();

const rateLimiterMiddleware = (req, res, next) => {
  const currentTime = Date.now();
  const clientIP = req.ip;
  
  const requestLog = requestsForWindow.get(clientIP) || [];
  const requestsWithinWindow = requestLog.filter(time => currentTime - time < rateLimitWindowInMs);
  
  if (requestsWithinWindow.length >= maxRequestsPerWindow) {
    res.status(429).json({ message: 'Too many requests. Please try again later.' });
  } else {
    requestsWithinWindow.push(currentTime);
    requestsForWindow.set(clientIP, requestsWithinWindow);
    next();
  }
};

app.use(rateLimiterMiddleware);

app.get('/', (req, res) => {
  res.send('Hello, world!');
});

const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server is running on port ${port}`));

In this example, we create an Express app and define a rate limiter middleware called ‘rateLimiterMiddleware‘. It maintains a ‘Map‘ object‘ requestsForWindow‘, which stores an array of timestamps for each IP address. In the middleware, we limit the number of allowed requests according to the ‘maxRequestsPerWindow‘ parameter.

**Method 2: Rate limiting using Redis**

Using a centralized data store like Redis helps when you need to share the rate limit information across multiple instances or different services in your application. You may need to install Redis on your computer and run the Redis service.

1. First, install ‘Express‘ and ‘ioredis‘:

$ npm install express ioredis

2. Create an ‘index.js‘ file, and paste the code below:

const express = require('express');
const Redis = require('ioredis');
const app = express();

const redis = new Redis({ host: '127.0.0.1', port: 6379 });

const rateLimitWindowInMs = 60 * 1000; // 1 minute
const maxRequestsPerWindow = 10;

const rateLimiterMiddleware = async (req, res, next) => {
  const currentTime = Date.now();
  const clientIP = req.ip;
  const timeWindow = Math.floor(currentTime / rateLimitWindowInMs);
  
  const key = `rate-limit:${clientIP}-${timeWindow}`;
  
  try {
    const requestCount = await redis.get(key);
  
    if (requestCount >= maxRequestsPerWindow) {
      res.status(429).json({ message: 'Too many requests. Please try again later.' });
    } else {
      await redis.multi()
        .incr(key)
        .expire(key, (rateLimitWindowInMs / 1000) + 1)
        .exec();
      next();
    }
  } catch (err) {
    console.error('Redis error:', err);
    res.status(500).json({ message: 'Internal server error.' });
  }
};

app.use(rateLimiterMiddleware);

app.get('/', (req, res) => {
  res.send('Hello, world!');
});

const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server is running on port ${port}`));

In this example, we use the ‘ioredis‘ library to connect to the Redis server. The rate-limiter middleware using Redis increments the request count for each IP address and sets an expiration time according to the time window.

Both of these methods can effectively limit the rate of incoming requests to your Node.js server. However, the Redis-based method is more suitable for distributed applications or scenarios where multiple instances of your application need to share rate-limiting data.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Node.js interview — then scores it.
📞 Practice Node.js — free 15 min
📕 Buy this interview preparation book: 100 Node.js questions & answers — PDF + EPUB for $5

All 100 Node.js questions · All topics