-
-
Notifications
You must be signed in to change notification settings - Fork 168
MySQL
It supports mysql2
, mysql
, sequilize
and knex
.
Note: It takes 50-150 ms per request on more than 1000 concurrent requests per second. Be careful, when using in applications with high traffic.
By default, RateLimiterMySQL creates rtlmtrflx
database and a new table by keyPrefix
for every limiter.
All limits are stored in one table if tableName
option is set.
To change the database name set option dbName
.
RateLimiterMySQL
throws error on limiter creation, if database or table can NOT be created.
MySQL connections typically take milliseconds to establish. During this connection period, any rate limiter method calls will be rejected with an Error until the connection is fully established.
For proper error handling, we recommend providing a ready callback as the second parameter when creating a new instance: new RateLimiterMySQL(opts, ready)
. This callback allows you to handle any errors that occur during database or table creation for rate limiters (see example below).
The ready callback is optional if your process automatically terminates on unhandled errors.
Rows that expired more than an hour ago are removed every 5 minutes by setTimeout
. Note, call rateLimiter.clearExpired(Date.now() - 3600000)
manually to remove expired rows in AWS Lambda or GCP function.
See detailed options description here
const mysql = require('mysql2');
const {RateLimiterMySQL} = require('rate-limiter-flexible');
const pool = mysql.createPool({
connectionLimit : 100,
host: 'localhost',
user: 'root',
password: 'secret',
});
const opts = {
storeClient: pool,
dbName: 'mydb',
tableName: 'mytable', // all limiters store data in one table
points: 5, // Number of points
duration: 1, // Per second(s)
};
const ready = (err) => {
if (err) {
// some error happened during database or table creation
} else {
// db and table checked or created. limiter can be used now
}
};
// if second parameter is not a function or not provided, it may throw unhandled error on database or table creation
const rateLimiter = new RateLimiterMySQL(opts, ready);
rateLimiter.consume(key)
.then((rateLimiterRes) => {
// 1 points consumed
})
.catch((rej) => {
// there are no more points
});
It gets internal connection from Sequelize or Knex to make raw queries. After making query, the connection is released.
const rateLimiter = new RateLimiterMySQL({
storeClient: sequelizeInstance,
}, ready);
const rateLimiter = new RateLimiterMySQL({
storeClient: knexInstance,
storeType: `knex`, // knex requires this option
}, ready);
See detailed options description here
Endpoint is pure NodeJS endpoint launched in node:10.5.0-jessie
and mysql:5.7
Docker containers with 4 workers
Endpoint is limited by RateLimiterMySQL
with config for 500 random keys:
new RateLimiterMySQL({
storeClient: mysql,
points: 4, // Number of points
duration: 1, // Per second(s)
});
By bombardier -c 500 -l -d 30s -r 1000 -t 5s http://127.0.0.1:3000
Test with 500 concurrent requests with maximum 1000 requests per sec during 30 seconds
Statistics Avg Stdev Max
Reqs/sec 1000.96 250.22 2171.97
Latency 20.88ms 17.01ms 141.73ms
Latency Distribution
50% 12.94ms
75% 28.33ms
90% 48.01ms
95% 59.89ms
99% 85.00ms
HTTP codes:
1xx - 0, 2xx - 24684, 3xx - 0, 4xx - 5322, 5xx - 0
Statistics Avg Stdev Max
Reqs/sec 1002.28 299.86 2669.58
Latency 14.59ms 6.13ms 102.96ms
Latency Distribution
50% 12.91ms
75% 16.84ms
90% 20.58ms
95% 25.60ms
99% 38.66ms
HTTP codes:
1xx - 0, 2xx - 24647, 3xx - 0, 4xx - 5357, 5xx - 0
Get started
Middlewares and plugins
Migration from other packages
Limiters:
- Valkey Glide
- IoValkey
- Redis
- Memory
- DynamoDB
- Prisma
- Etcd
- MongoDB (with sharding support)
- PostgreSQL
- MySQL
- SQLite
- BurstyRateLimiter
- Cluster
- PM2 Cluster
- Memcached
- RateLimiterUnion
- RateLimiterQueue
Wrappers:
- RLWrapperBlackAndWhite Black and White lists
Knowledge base:
- Block Strategy in memory
- Insurance Strategy
- 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