Rate Limiting in TypeScript: Libraries, Strategies, and Examples

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 TypeScript: A Complete Guide to Libraries and Implementation



Rate limiting is a traffic control mechanism that prevents server overload, protects against DDoS attacks, and ensures even resource distribution. In TypeScript, thanks to strict typing and async support, implementing rate limiting becomes especially convenient. In this article, we will cover popular libraries, strategies, and code examples for TypeScript.



Why is Rate Limiting Needed?

  • API Protection — limiting the number of requests from a single client (by IP, token, or ID).
  • Abuse Prevention — blocking bots or scripts generating excessive load.
  • Resource Distribution — fair usage of the backend among users.
  • Compliance with External Service Limits — controlling requests to third-party APIs (e.g., OpenAI or GitHub).


Popular Libraries for Rate Limiting in TypeScript



1. express-rate-limit

The most popular library for Express.js. Works as middleware, supports TypeScript out of the box. Allows setting time-based limits and custom exceed handlers.

Installation:

npm install express-rate-limitnpm install -D @types/express-rate-limit

Usage Example:

import express from 'express';import rateLimit from 'express-rate-limit';

const app = express();

const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // max 100 requests per window message: 'Too many requests, please try again later.', standardHeaders: true, legacyHeaders: false,});

app.use('/api', limiter); // Apply to /api/*

app.get('/api/data', (req, res) => { res.json({ message: 'Successful response' });});

app.listen(3000);

Features:

  • Built-in TypeScript support (types for Request and Response).
  • Flexible configuration: can set a key (by IP, userId, token).
  • State storage in memory (default) or via Redis.


2. bottleneck

A library for client-side rate limiting — ideal when you need to control outgoing requests (e.g., to an external API). Works based on queues and delays.

Installation:

npm install bottleneck

TypeScript Example:

import Bottleneck from 'bottleneck';

const limiter = new Bottleneck({ minTime: 200, // minimum 200 ms between requests maxConcurrent: 5, // maximum 5 concurrent requests reservoir: 100, // total limit for the period reservoirRefreshAmount: 100, reservoirRefreshInterval: 60 * 1000, // every 60 seconds});

async function fetchData(id: number): Promise<string> { const response = await fetch(`https://api.example.com/data/${id}`); return response.text();}

// Wrap the function with rate limitingconst limitedFetch = limiter.wrap(fetchData);

// Usageasync function main() { const results = await Promise.all([ limitedFetch(1), limitedFetch(2), limitedFetch(3), ]); console.log(results);}

Pros:

  • Supports types for the wrapped function.
  • Flexible strategies: minTime, maxConcurrent, reservoir.
  • Works both in Node.js and in the browser.


3. p-limit

A lightweight library for limiting parallel async operations. Useful when you need to control the number of concurrently executing promises.

Installation:

npm install p-                    

Recommendations