ratelimiter.io is the easiest way to add basic ratelimiting to your app.
It's offered as both an MIT-licensed open-source project and a free hosted service that does not require any registration. It costs me money to run the hosted service, so if you find it valuable, I encourage you to throw me a few bucks.
Rate limiting is a very useful technique to prevent abuse and manage costs. For example, you can:
- Limit the number of requests per user on an expensive endpoint to control costs.
- Limit the number of login attempts per IP to prevent account compromise.
- Limit the number of messages a user can send per hour to prevent spam.
Almost every real-world application could benefit from rate limiting, but it requires setting up custom infrastructure (such as Redis) which can be a hassle. ratelimiter.io is a completely free hosted rate limiting service that you can use without setting anything up, and all of the code is open-source if you want to run it yourself.
First, install the client library.
npm install ratelimiter.io
Next, call it.
import { throwIfRateLimited } from "ratelimiter.io";
// use callRatelimit() if you want access to the API response
await throwIfRateLimited({
// string corresponding to your app. ideally, this would be a long, unique string, like a uuid
appId: "my_cool_app",
// name of the event you want to limit
eventName: "account_created",
// how many events are allowed
quota: 60,
// in what time window
timeWindowSeconds: 60,
// strings identifying the entities (user id, email, phone etc) associated with the user
// the client library computes a salt based on the appId and hashes these entities
entities: ["uid=1234", "email=foo@bar.com", "ip=1.2.3.4"],
});
Just do a simple HTTP request:
curl -XPOST https://ratelimiter.io/api/ratelimit \
-H 'Content-type: application/json' \
-d '{"quota": 60, "time_window_seconds": 60, "app_id": "my_cool_app", "event_name": "message_sent", "entities": ["email_hash", "ip_hash", "user123"]}'
{
"ok": true,
"entities": {
"email_hash": {"remaining": 59, "total": 1, "reset": 124123515},
"ip_hash": {"remaining": 59, "total": 1, "reset": 124123515},
"user123": {"remaining": 59, "total": 1, "reset": 124123515},
}
}
The endpoint takes the following parameters:
- quota: the number of events in the time window you want to allow
- time_window_ms: the size of the time window in seconds
- app_id: a string that's unique to your app. This is effectively a namespace and ensures that your rate limits don't collide with those of other apps. Generate one by running
node -e 'console.log(require("crypto").randomBytes(32).toString("hex"))'
oropenssl rand 32 -hex
- event_name: the event you want to rate limit. For example,
logged_in
,account_created
,message_sent
etc. - entities: a list of strings representing the user doing the action. This is usually email addresses, IP addreses, phone numbers, ISP names, etc. Ideally you would salt and hash these before sending them to use because we don't want your personal data.
We salt and hash the entities
you send us (it's best if you do this client-side too, which is done automatically for you if you use the npm package). All data is deleted when it expires.
On a Redis box in Digital Ocean NYC.
No. If you would like one, reach out on Twitter for a commercial license or run your own instance.
This is basically a very API wrapper around async-ratelimiter that I'm hosting for others.