-
-
Notifications
You must be signed in to change notification settings - Fork 185
Drizzle
Roman edited this page Feb 1, 2026
·
9 revisions
It was tested with PostgreSQL.
- Create schema.js in drizzle directory.
// schema.js
import {pgTable, text, integer, timestamp} from "drizzle-orm/pg-core"
export const rateLimiterFlexibleSchema = pgTable('RateLimiterFlexible', {
key: text('key').primaryKey(),
points: integer('points').notNull(),
expire: timestamp('expire'),
})- Create drizzle.config.js in drizzle directory.
// drizzle.config.js
import { defineConfig } from 'drizzle-kit'
export default defineConfig({
out: './drizzle',
schema: './schema.js',
dialect:"postgresql",
dbCredentials: {
url:"postgres://root:secret@127.0.0.1:5432",
},
})-
Run
npx drizzle-kit pushfrom drizzle directory. -
Use this code in your app.
const { drizzle } = require("drizzle-orm/node-postgres")
const { RateLimiterDrizzle } = require('rate-limiter-flexible')
const { rateLimiterFlexibleSchema } = require('./drizzle/schema')
const db = drizzle("postgres://root:secret@127.0.0.1:5432")
const rateLimiter = new RateLimiterDrizzle({
storeClient: db,
schema: rateLimiterFlexibleSchema,
points: 3, // Number of points
duration: 1, // Per second
})
async function rateLimit(userId) {
try {
const rlRes = await rateLimiter.consume(userId, 1) // consume 1 point
console.log(rlRes)
// {
// remainingPoints: 2,
// msBeforeNext: 976,
// consumedPoints: 1,
// isFirstInDuration: true
// }
} catch (rejRes) {
if (rejRes instanceof Error) {
// Some error
// It never happens if `insuranceLimiter` is configured
} else {
// If there is no error, rejRes promise is rejected with number of ms before next request allowed
//
// For example, in express.js you could set headers and send 429
// const secs = Math.round(rejRes.msBeforeNext / 1000) || 1;
// res.set('Retry-After', String(secs));
// res.status(429).send('Too Many Requests');
}
throw rejRes
}
}Instead of userId any identifier like email or IP address can be used.
It doesn't guarantee precise events count under race conditions, but much faster than atomic limiter. Ideal for protection against DoS attacks.
Replace RateLimiterDrizzle with RateLimiterDrizzleNonAtomic. Everything else works the same as in atomic limiter.
const { RateLimiterDrizzleNonAtomic } = require('rate-limiter-flexible')Get started
Middlewares and plugins
Migration from other packages
Limiters:
- Cluster
- Drizzle
- DynamoDB
- Etcd
- Memcached
- Memory
- MongoDB (with sharding support)
- MySQL
- PM2 Cluster
- PostgreSQL
- Prisma
- Redis
- SQLite
- Valkey: iovalkey and Valkey Glide
- BurstyRateLimiter
- RateLimiterUnion
- RateLimiterQueue
Wrappers:
- AWS SDK v3 Client Rate Limiter
- RLWrapperBlackAndWhite Black and White lists
- RLWrapperTimeouts Timeouts
Knowledge base:
- Block Strategy in memory
- Insurance Strategy
- Periodic sync to reduce number of requests
- Comparative benchmarks
- Smooth out traffic peaks
-
Usage example
- Minimal protection against password brute-force
- Login endpoint protection
- Websocket connection prevent flooding
- Dynamic block duration
- Different limits for authorized users
- Different limits for different parts of application
- Block Strategy in memory
- Insurance Strategy
- Third-party API, crawler, bot rate limiting