bufferq runs as a sidecar middleware next to your API — no proxy, no DNS changes. It works out who's actually calling: human, script, or autonomous agent. Then it decides to let them through, grant them a slot, or queue them with a token to come back. 402 native and HATEOAS native for better understanding from agents.
Over the limit, a caller gets a token and a link to the next request. Come back, ask again, get a real answer.
{
"outcome": "Queued",
"callerType": "Agent",
"granted": false,
"leaseToken": "061F6A05…70CA",
"reason": "rate_limit_exceeded",
"links": {
"poll": { "href": "/api/accessgate/poll", "method": "POST" }
}
}{
"granted": true,
"leaseToken": "ea530bb0…1c0c92",
"reason": "poll_granted_within_rate_limit",
"links": {
"complete": { "href": "/api/accessgate/complete", "method": "POST" }
}
}Call the gate over HTTP or gRPC — whichever your sidecar already speaks.
Available today for JavaScript and .NET.
Both are live in bufferq today — the same classification and policy engine, pointed at different traffic.
Tool-call fan-outs fire five to thirty parallel requests in under fifty milliseconds, with near-zero dwell time between a response and the next dependent call. A static per-IP limiter can't tell that apart from an attack — it just drops things.
Issue a key, attach a requests-per-minute policy, and bufferq enforces it — atomically, under concurrency, with no race between the request that got through and the one that didn't. Callers that are over the limit get a token back, not a dead end.
Not a pipeline diagram — this is the actual sequence, in the order it runs.
The sidecar calls bufferq before the backend does any work — route, tenant, the caller's User-Agent and IP, and an API key + policy if one was presented.
No key: bufferq classifies the caller — Agent, StandardApi, Human, or Unknown — from request signals. A key: its rate-limit policy takes over instead.
Only reachable from Queued. The caller asks "can I come in now?" bufferq re-checks the same window and either mints a real lease or says wait — and the response carries a links object naming the next request (poll again, or complete), so the caller doesn't have to hardcode routes to find out.
A Granted response carries a complete link. A Queued response carries a poll link. A caller doesn't need to know the API ahead of time — it follows what the response gives it, not a hardcoded route.
BillWalled is wired to a real HTTP 402 in the controller — the status code fires the moment the service can produce it. No capacity rule or payment processor decides that yet.
bufferq runs as a sidecar, in front of every call. A gate that's slower than the request it's guarding defeats the point of a sidecar — every rate-limit and classification check is held to that target.
A sidecar next to your API. No proxy, no DNS changes.