Vetrix Docs

Rate Limits

The gitvetrix.com API meters requests with a Redis-backed token-bucket limiter. Each request is classified into a scope, and each scope has a per-identity budget that depends on the caller's user group. A request that exhausts its budget receives 429 Too Many Requests with standard rate-limit headers. For the error envelope and other status codes see errors.md.

Scopes

Every route is labeled with one rate-limit scope. The seven canonical scopes have a configurable budget for each user group:

Scope Covers
api.read Read-only REST endpoints (the default for any labeled route)
api.write Mutating REST endpoints
api.expensive Costly operations (large queries, presigned-URL minting, exports)
git.read Git fetch / clone over HTTP
git.write Git push over HTTP
registry OCI, npm, PyPI, and Go module registry traffic
beacon Telemetry / beacon endpoints

One additional scope, mcp.tool_call, meters Model Context Protocol tool calls. It is kept separate from api.write so AI-assistant traffic cannot starve REST traffic through a shared counter. Its ceiling is governed by the mcp.rate_limit.calls_per_min admin setting (default 120 calls per minute per token); a value of 0 makes it inherit the api.write budget.

Budgets by user group

Three user-group tiers ship with default budgets. Custom groups created by an operator inherit the general tier's budget until overridden. Each rule is requests per window over a window (60 seconds for all seeded rules), with a burst allowance and an action.

Anonymous (unauthenticated callers)

Scope Requests / min Burst Action
api.read 60 10 throttle
api.write 10 0 throttle
api.expensive 5 0 throttle
git.read 30 5 throttle
git.write disabled (anonymous push is refused)
registry 60 10 throttle
beacon 120 20 throttle

General (authenticated users)

Scope Requests / min Burst Action
api.read 600 60 throttle
api.write 120 20 throttle
api.expensive 30 5 throttle
git.read 300 30 throttle
git.write 60 10 throttle
registry 300 30 throttle
beacon 600 60 throttle

Admin (instance administrators)

Scope Requests / min Burst Action
api.read 6000 600 allow
api.write 1200 120 allow
api.expensive 300 30 allow
git.read 3000 300 allow
git.write 600 60 allow
registry 3000 300 allow
beacon 6000 600 allow

The admin tier uses the allow action: requests are metered but not throttled, so an administrator is never locked out by a rule. There is no hardcoded bypass — the behavior comes entirely from the seeded allow action.

These are the shipped defaults. An operator can change any budget, and the limits can only be narrowed (never widened) by per-repository, per-OAuth-application, per-token, and per-user overrides. When more than one applies, the smallest effective rate wins.

The 429 response

When a request exceeds its budget under a throttle rule, the API returns 429 Too Many Requests with the standard error envelope and the following headers:

Header Meaning
X-RateLimit-Limit The budget (requests per window) for this scope
X-RateLimit-Remaining Requests left in the current window
X-RateLimit-Reset Unix timestamp (seconds) when the window resets
X-RateLimit-Scope The scope this request was metered against
Retry-After Seconds to wait before retrying (minimum 1)

The X-RateLimit-* headers are also emitted on throttled responses that were allowed (still within budget), so a client can observe how close it is to a limit. Retry-After is present only when the request was actually denied.

A well-behaved client reads Retry-After and backs off for at least that many seconds before retrying.

Operational behavior

  • Redis-backed. Token buckets live in Redis, keyed per identity and scope, so limits hold across every API node.
  • Fail-open. If Redis is unreachable, requests pass through unmetered and no rate-limit headers are emitted. Tolerating an unprotected window is the deliberate tradeoff over locking everyone out.
  • Kill switch. Rate limiting has a master enable switch; when it is off, every request passes without metering.
  • Shadow mode. The limiter can run in shadow mode, where decisions are computed and headers are emitted but no request is actually rejected. This is used to observe the effect of a budget change before enforcing it.