Skip to content

Rate-limit your API's customers

Say your product has its own public API, and each customer calls it with their own API key. You want each key to make at most 60 requests in any minute and 1,000 in any hour, so one customer’s script can’t slow everyone else down.

One over any minute for bursts, and one over any hour, both on the subject kind apikey:

Terminal window
curl -X POST https://api.limitry.com/v1/limits \
-H "Authorization: Bearer $LIMITRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"API burst","subjectKind":"apikey","action":"api-request",
"amount":60,"window":"minute","rolling":true}'
curl -X POST https://api.limitry.com/v1/limits \
-H "Authorization: Bearer $LIMITRY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"API per hour","subjectKind":"apikey","action":"api-request",
"amount":1000,"window":"hour","rolling":true}'

Rolling windows count the last 60 seconds or 60 minutes at the moment of each request, so there’s no burst allowed at the top of the hour.

Check before handling the request, using your customer’s key id as the subject. Both limits apply, and the request is allowed only if it fits both:

import { createClient, createLimits, LimitExceeded } from "@limitry/sdk";
const limits = createLimits(
createClient({ token: process.env.LIMITRY_API_KEY! }),
);
export async function handle(request: Request, customerKeyId: string) {
try {
return await limits.guard(
{ subject: { kind: "apikey", id: customerKeyId }, action: "api-request" },
() => route(request),
);
} catch (err) {
if (err instanceof LimitExceeded) {
return new Response("Too many requests", {
status: 429,
headers: { "Retry-After": String(err.retryAfterSeconds ?? 60) },
});
}
throw err;
}
}

Both limits keep the default fail mode, open: if Limitry can’t be reached, requests go through rather than your API going down with it.

Every limit that matches a request applies, so a limit for one key (with subjectId set) can lower that key’s allowance but not raise it. To give customers on a bigger plan more, use a subject kind per plan, such as apikey-pro with its own limits, and send that kind for their keys.

The Usage page shows, for each limit, the keys using it right now and how many of their requests were turned away.

Related: Rolling windows and concurrency, Checks.