@unkey/ratelimit
Serverless ratelimiting
( Globally consistent, fast ) - choose two
@unkey/ratelimit
is a library for fast global ratelimiting in serverless functions.
TLDR:
const { success } = await unkey.limit("my-user-id")
if (!success){
// reject request
}
// handle request
github.com/unkeyed/unkey/tree/main/packages/ratelimit
Install
npm install @unkey/ratelimit
Configure your ratelimiter
import { Ratelimit } from "@unkey/ratelimit"
const unkey = new Ratelimit({
rootKey: process.env.UNKEY_ROOT_KEY,
namespace: "my-app",
limit: 10,
duration: "30s",
async: true
})
Use it
async function handler(request) {
const identifier = request.getUserId() // or ip or anything else you want
const ratelimit = await unkey.limit(identifier)
if (!ratelimit.success){
return new Response("try again later", { status: 429 })
}
// handle the request here
}
Making it bullet proof
Everything we do is built for scale and stability. We built on some of the world’s most stable platforms (Planetscale and Cloudflare) and run an extensive test suite before and after every deployment.
Even so, we would be fools if we wouldn’t explain how you can put in safe guards along the way.
In case of severe network degredations or other unforseen events, you might want to put an upper bound on how long you are willing to wait for a response from unkey.
By default the SDK will reject a request if it hasn’t received a response from unkey within 5 seconds. You can tune this via the timeout
config in the constructor (see below).
The SDK captures most errors and handles them on its own, but we also encourage you to add a onError
handler to configure what happens in case something goes wrong.
Both fallback
property of the timeout
config and onError
config are callback functions. They receive the original request identifier as one of their parameters, which you can use to determine whether to reject the request.
import { Ratelimit } from "@unkey/ratelimit"
// In this example we decide to let requests pass, in case something goes wrong.
// But you can of course also reject them if you want.
const fallback = (identifier: string) => ({ success: true, limit: 0, reset: 0, remaining: 0 })
const unkey = new Ratelimit({
// ... standard stuff
timeout: {
ms: 3000, // only wait 3s at most before returning the fallback
fallback
},
onError: (err, identifier) => {
console.error(`${identifier} - ${err.message}`)
return fallback(identifier)
}
})
const { success } = await unkey.limit(identifier)
API
new Ratelimit(config: RatelimitConfig)
Create a new instance for ratelimiting by providing the necessary configuration.
.limit(identifier: string, opts: LimitOptions): Promise<RatelimitResponse>
Check whether a specific identifier is currently allowed to do something or if they have currently exceeded their limit.
RatelimitResponse
Was this page helpful?