Rate limits
Each API key, admin or project, makes at most N requests a minute on each node, where N is api.rate_limit_per_minute. The default is 600.
One budget for the API and MCP
The key has one budget for both interfaces.
Counted:
- every request to a route under
/api/v1/…that passed authentication, whatever its status (200,404,413,422); - every HTTP request to the MCP path (
mcp.path, default/mcp) that passed authentication. Each client message counts:initialize,notifications/initialized,tools/listand eachtools/call.
Not counted and not limited:
- requests rejected with
401; - an unknown path under
/api/v1(404before authentication); /healthz,/readyz,/metricsand/api/openapi.json.
The limit comes before everything the request does and does not touch the storage.
How the budget refills
The algorithm is GCRA (generic cell rate algorithm). A key can make N requests in a row; after that it earns one more request every 60 s / N. A minute without requests returns the whole budget.
There is no window aligned to the minute. In any 60 s at most 2N − 1 requests pass: the full budget plus what the key earns during those 60 s.
Over the limit
{
"type": "https://postwind.dev/errors/rate_limited",
"title": "…",
"status": 429,
"detail": "…",
"code": "rate_limited"
}
- The status is
429with coderate_limited. Retry-Afteris the number of seconds until the key’s next request passes, rounded up, at least 1. Thedetailnames the same number.- A request that arrives after
Retry-Afterseconds passes. - A refused request does not spend the budget, so repeats before that time do not push it further away.
MCP answers the same 429 at the HTTP level, byte for byte as the API. It is not a tool error and not a JSON-RPC error.
Per node, not per cluster
The budget lives in the memory of each node. Behind a load balancer with M nodes that serve the API and MCP, a key can make up to M × N requests a minute. A node restart gives every key its whole budget back.
Size limits
- A request body is at most 10 MB, in the API and in MCP. A larger one is
413 body_too_large. See Request bodies. - Importing subscribers takes at most 10 000 records per request (
import_subscribers). The MCP tool takes at most 1 000 per call.