Skip to content

Drizzle

Roman edited this page Feb 1, 2026 · 9 revisions

RateLimiterDrizzle

It was tested with PostgreSQL.

Usage

  1. 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'),
})
  1. 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",
  },
})
  1. Run npx drizzle-kit push from drizzle directory.

  2. 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.

Non-atomic

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')

Clone this wiki locally