Rate Limit Mongo Store

raw JSON →
2.3.2 verified Thu Apr 23 auth: no javascript

rate-limit-mongo is a specialized MongoDB store designed for the popular `express-rate-limit` middleware, currently at version 2.3.2. This package provides a persistent, database-backed storage mechanism for rate limiting records, moving beyond in-memory or Redis solutions. It leverages MongoDB's TTL (Time-To-Live) indexes to automatically expire rate limiting entries, ensuring efficient cleanup and preventing stale data. While not on a strict release cadence, updates typically align with bug fixes or `express-rate-limit`/MongoDB driver compatibility improvements. Its primary differentiation lies in offering a robust, low-configuration MongoDB-specific solution for managing API rate limits, particularly beneficial for applications already using MongoDB and requiring shared, persistent rate limit counters across multiple instances.

error MongoNetworkError: failed to connect to server [127.0.0.1:27017] on first connect
cause The MongoDB server is not running or the connection URI is incorrect.
fix
Ensure the MongoDB server is running and accessible from the application host. Verify the uri provided in the MongoStore configuration is correct and points to an active MongoDB instance.
error MongoError: Authentication failed.
cause Incorrect username or password provided for MongoDB authentication.
fix
Verify that the user and password fields in the MongoStore configuration match valid MongoDB credentials with access to the specified database or authSource.
error Error: TTL index 'expirationDate_1' already exists with different options.
cause An existing index with the same name on the `expirationDate` field has different `expireAfterSeconds` settings than what `rate-limit-mongo` expects (which is 0).
fix
Drop the existing index (db.collection.dropIndex('expirationDate_1')) or ensure the createTtlIndex option is set to false if you manage the index manually with the correct expireAfterSeconds: 0 setting.
gotcha The `expireTimeMs` option in `rate-limit-mongo` and the `windowMs` option in `express-rate-limit` should be set to identical values. Mismatching these values will result in incorrect `Retry-After` headers being sent to clients.
fix Ensure `expireTimeMs` in `MongoStore` options and `windowMs` in `RateLimit` options are numerically equivalent (e.g., both 15 * 60 * 1000 for 15 minutes).
gotcha MongoDB TTL indexes operate on a background task that runs every 60 seconds. Consequently, expired documents may persist in the collection for a period between their expiration and the task's execution.
fix Account for this delay in application logic if strict immediate deletion is required, or consider shorter `expireTimeMs` for more aggressive cleanup (though this increases database write load).
gotcha By default, `rate-limit-mongo` attempts to create a TTL index on the collection. If the MongoDB user lacks permissions for index creation, this operation will fail. The `createTtlIndex: false` option can suppress this behavior.
fix If index creation fails or is not desired from the application, set `createTtlIndex: false` in the `MongoStore` options and ensure the TTL index is manually created on the collection (`db.collection.createIndex({ expirationDate: 1 }, { expireAfterSeconds: 0 })`).
gotcha The default MongoDB connection options `useUnifiedTopology: true` and `useNewUrlParser: true` are implicitly applied. These options may become deprecated or change behavior in future versions of the MongoDB Node.js driver.
fix Monitor `mongodb` driver release notes for changes to connection options. Explicitly define all desired connection options via the `connectionOptions` property to maintain control over connection behavior.
npm install rate-limit-mongo
yarn add rate-limit-mongo
pnpm add rate-limit-mongo

This code demonstrates the basic setup of `rate-limit-mongo` as a store for `express-rate-limit`, configuring connection details and matching `expireTimeMs` with `windowMs`.

const RateLimit = require('express-rate-limit');
const MongoStore = require('rate-limit-mongo');

const limiter = new RateLimit({
  store: new MongoStore({
    uri: process.env.MONGO_URI ?? 'mongodb://127.0.0.1:27017/test_db',
    user: process.env.MONGO_USER ?? '',
    password: process.env.MONGO_PASSWORD ?? '',
    expireTimeMs: 15 * 60 * 1000, // Should match windowMs
    errorHandler: console.error.bind(null, 'rate-limit-mongo store error')
  }),
  max: 100,
  windowMs: 15 * 60 * 1000 // Should match expireTimeMs
});

// Example of how to apply it in an Express app (assuming 'app' is an Express instance)
// app.use(limiter);