MongoDB Store
The MongoDB store enables distributed rate limiting using your existing MongoDB database. Ideal for teams running MEAN/MERN stacks or MongoDB Atlas who want to add rate limiting without introducing Redis or Postgres.
Installation
The MongoDB store requires mongodb as a peer dependency:
npm install mongodb
# or: pnpm add mongodb
# or: yarn add mongodb bun add mongodb Usage
import { hitlimit } from '@joint-ops/hitlimit'
import { mongoStore } from '@joint-ops/hitlimit/stores/mongodb'
import { MongoClient } from 'mongodb'
const client = new MongoClient('mongodb://localhost:27017')
await client.connect()
const db = client.db('myapp')
app.use(hitlimit({
limit: 100,
window: '1m',
store: mongoStore({ db })
})) import { hitlimit } from '@joint-ops/hitlimit-bun'
import { mongoStore } from '@joint-ops/hitlimit-bun/stores/mongodb'
import { MongoClient } from 'mongodb'
const client = new MongoClient('mongodb://localhost:27017')
await client.connect()
const db = client.db('myapp')
const limiter = hitlimit({
limit: 100,
window: '1m',
store: mongoStore({ db })
}) Options
| Option | Type | Default | Description |
|---|---|---|---|
db | Db | - | A MongoDB Db instance from MongoClient.db() (required) |
collectionPrefix | string | 'hitlimit' | Prefix for rate limit collection names |
skipIndexCreation | boolean | false | Skip automatic TTL and unique index creation on startup |
TTL Indexes
The MongoDB store automatically creates TTL indexes on all collections. MongoDB's background thread deletes expired documents automatically — no cleanup timers needed.
Each collection has an expireAt field with a TTL index (expireAfterSeconds: 0). When the expireAt timestamp passes, MongoDB removes the document within ~60 seconds.
// TTL indexes created automatically:
{ expireAt: 1 }, { expireAfterSeconds: 0 }
// Unique key indexes for upsert operations:
{ key: 1 }, { unique: true } Schema
The store creates three collections (prefix defaults to hitlimit):
// hitlimit_hits
{ key: "string", count: number, resetAt: number, expireAt: Date }
// hitlimit_bans
{ key: "string", expiresAt: number, expireAt: Date }
// hitlimit_violations
{ key: "string", count: number, resetAt: number, expireAt: Date } MongoDB Atlas
Connect to MongoDB Atlas using a connection string:
const client = new MongoClient(
'mongodb+srv://user:password@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority'
)
await client.connect()
const db = client.db('myapp')
mongoStore({ db }) Bun Compatibility
The mongodb 6.x driver is pure JavaScript and works with Bun, but there are known issues
to be aware of:
- TLS connections may fail — MongoDB Atlas and other TLS-enabled connections can fail under Bun due to TLS handling differences (Bun issues #17913, #24374). Use localhost or non-TLS connections for Bun.
- Memory leaks — Some users report ~8-12MB/hr memory growth with the MongoDB driver on Bun (issue #24118).
Recommendation: For production MongoDB with TLS, use Node.js. For localhost/non-TLS development or testing, Bun works reliably. Node.js has no such limitations.
Characteristics
- Persistence: Full MongoDB durability (journaling, replica sets)
- Scalability: Shared across all server instances
- Atomic:
findOneAndUpdatewith aggregation pipeline ensures race-condition-free increments - Cleanup: Automatic via MongoDB TTL indexes (no timers needed)
- Dependencies: Requires
mongodbdriver (>=6.0.0)
When to Use
- Teams already running MongoDB in production
- MEAN/MERN stack applications
- MongoDB Atlas or DocumentDB users
- When you want distributed rate limiting without adding Redis or Postgres
- NoSQL-first architectures