statshawk
Getting started

Rate limits

Per-account requests-per-second ceilings, the headers that track them, and how to back off.

How it works

In addition to your monthly quota, every account has a requests-per-second ceiling set by its plan. The limiter is a GCRA ("leaky bucket") applied per account: shared across all of your API keys and every replica of the API. You can burst up to one second of budget at once; the budget then refills continuously at your plan's rate.

PlanRequests / second
Free5
Hobby10
Pro50
Scale200
Growth1,000
Enterprise5,000

When you outpace the refill you receive 429 Too Many Requests:

rate limit body
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Retry after 1 seconds."
  }
}

Throttled responses include a Retry-After header (whole seconds, rounded up, under a per-second limiter it is effectively always 1). Honor it: sleep, then resume.

Response headers

Metered customer endpoints carry the request-rate headers. (Operator and asset routes, /v1/ingest/* and /v1/assets/*, including the public team-logo endpoint, bypass the account limiter entirely and carry neither these headers nor the ceiling.)

HeaderValue
X-RateLimit-LimitYour plan's requests-per-second ceiling
X-RateLimit-RemainingRequests left in the current one-second budget
X-RateLimit-ResetUnix timestamp (whole seconds, rounded up) when the budget is fully refilled

Sustained throughput

The ceiling is per second, not per minute. A Free account can make 5 requests every second all day (that's 300/minute sustained) but cannot send 25 at once: a parallel burst of 25 yields 5 successes and 20 throttles. Pace bulk work to your plan's RPS and you will never see a 429.

If the limiter backend is unavailable

The limiter fails closed: if its backing store is unreachable, requests receive 503 Service Unavailable with error.code: "RATE_LIMIT_BACKEND_UNAVAILABLE" rather than running unmetered. Treat it like any other 5xx: exponential back-off; it clears when the backend recovers.

On this page