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:

import { createClient } from "@limitry/sdk";
const limitry = createClient();
await limitry.limits.create({
name: "API burst",
subjectKind: "apikey",
action: "api-request",
amount: 60,
window: "minute",
rolling: true,
});
await limitry.limits.create({
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. That’s the key your customer sends to your API, not your Limitry key. Both limits apply, and the request is allowed only if it fits both:

import { createClient, LimitExceeded } from "@limitry/sdk";
const limitry = createClient(); // reads LIMITRY_API_KEY
export async function handle(request: Request, customerKeyId: string) {
try {
return await limitry.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.

A limit for one key (with subjectId set) replaces the kind’s limit with the same action and window, so it can raise that key’s allowance or lower it. Use it for one customer you’ve agreed a deal with.

To give everyone 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.