Skip to content

Limits and retention

This page covers everything that bounds your traffic and your data on Gate: per-key and org-level rate limits, rolling usage caps on cost, tokens, and requests, the maximum request size, and how long Gate retains your logs, metrics, and audit records.


How rate limiting works

Every request to the gateway passes through two checks, in this order:

  1. Org-level rate limit. A requests-per-minute cap shared across every API key in your organization. Configured by your org admin in the dashboard or via the API.
  2. Per-key rate limit. An optional cap on a single API key. Useful for sandboxing CI pipelines, shared team keys, or untrusted clients.

Both layers use a sliding window of 60 seconds. Counters are maintained per key or per org, and they do not stack. If both are configured, the org-level limit is checked first. A rejection at either layer returns HTTP 429.

Note: In multi-replica deployments, rate limit counters are shared across all gateway replicas via a distributed store. Single-replica setups use an in-process store that is accurate but does not survive pod restarts.


Rate limit response headers

Rate limit headers are present when a limit applies to the request, so your client can track headroom without waiting for a rejection. They describe rate limiting only: a refusal for any other reason, such as a balance refusal, does not carry them. A request with no org limit and no per-key limit carries none of them. Which headers appear depends on which limit applied, and on whether the request was allowed or rejected.

Per-key headers

Per-key limits set X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. No X-RateLimit-Scope header is emitted for per-key limits.

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1749254400

Org-level headers

When an org-level limit is configured and the request is allowed, two extra headers carry the org window. The per-key headers, if a per-key limit also applies, describe the key’s own window:

X-RateLimit-Org-Limit: 1000
X-RateLimit-Org-Remaining: 823

When the org limit is what rejects the request, the 429 carries the org window in the generic headers plus the scope, and no X-RateLimit-Org-* pair:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1749254400
X-RateLimit-Scope: org
HeaderDescription
X-RateLimit-LimitThe cap that applies to this request.
X-RateLimit-RemainingRequests remaining before the active limit fires.
X-RateLimit-ResetUnix timestamp (seconds) when the current window resets.
X-RateLimit-Scopeorg on an org-level rejection, passthrough-ip on every keyless BYOK passthrough request. Not emitted for per-key limits.
X-RateLimit-Org-Limit(org limit only) The org-wide cap.
X-RateLimit-Org-Remaining(org limit only) Org-wide remaining. Present when the org limit is configured and the request was allowed; a rejection reports the same window in X-RateLimit-Remaining instead.

HTTP 429 response body

When any rate limit is exceeded the gateway returns HTTP 429 with an error body of the form:

{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after the reset window.",
"source": "gateway",
"retryAfter": 1749254400
}
}

For org-level rejections the message is:

{
"error": {
"code": "rate_limit_exceeded",
"message": "Organization rate limit exceeded. Please retry after the reset window.",
"source": "gateway",
"retryAfter": 1749254400
}
}
FieldDescription
codeAlways rate_limit_exceeded for rate limit rejections.
sourceAlways gateway. The request is stopped by Gate before the upstream is called.
retryAfterUnix timestamp (seconds) when you may safely retry.

The x-gate-error-source: gateway response header carries the same source value for clients that inspect headers.

Tip. Use retryAfter directly instead of sleeping for a fixed interval. The value is the exact window reset time, so you avoid both over-sleeping and premature retries.


Configuring rate limits

Per-key rate limit

Set rateLimit when creating or updating an API key via the keys API:

POST /api/v1/gateway/api-keys
Authorization: Bearer $GATE_API_KEY
Content-Type: application/json
{
"name": "CI pipeline key",
"orgId": "org_…",
"rateLimit": 60
}

rateLimit is requests per minute. Set it to null (or omit it) to remove the cap. The field is also editable via PATCH /api/v1/gateway/api-keys/:id.

Org-level rate limit

Org-level limits are not self-serve: the gatewayRateLimit field on the org’s entitlements row is the source of truth, and only Gate operators can set it. Ask support for the cap you need. null, the default, means no org cap is applied and only per-key limits are in play.


Usage limits (rolling spend/token/request caps)

In addition to per-minute rate limits, paid-plan organizations can create usage limits, soft ceilings on cost, token consumption, or request count over a rolling time window (1 hour, 1 day, 1 week, or 1 month). These are separate from the sliding-window rate limiter and are checked after rate limiting, before the upstream call.

Usage limits are managed via the keys API at /api/v1/gateway/usage-limits.

Note: Usage limits require a paid plan. Attempting to create or update a limit on a free-plan org returns 403.

Create a usage limit

POST /api/v1/gateway/usage-limits
Authorization: Bearer $GATE_API_KEY
Content-Type: application/json
{
"orgId": "org_…",
"name": "Daily token ceiling",
"limitType": "tokens",
"threshold": "5000000",
"timeWindow": "1 day"
}
FieldRequiredDescription
orgIdYesOrganization to apply the limit to.
nameYesHuman-readable label shown in the dashboard.
limitTypeYescost (USD), tokens (total tokens), or requests (request count).
thresholdYesNumeric string. For cost, this is USD (e.g. "25.00"). For tokens or requests, a whole number.
timeWindowYes"1 hour", "1 day", "1 week", or "1 month".
apiKeyIdNoScope the limit to a single key. Omit (or pass null) for an org-wide limit.
enabledNotrue (default) or false. Disabled limits are stored but not checked.

Update or delete

PATCH /api/v1/gateway/usage-limits/:id
DELETE /api/v1/gateway/usage-limits/:id

PATCH accepts the same optional fields as POST (all fields are optional on update). DELETE removes the limit permanently. It does not affect historical usage data.

Inspect current usage

GET /api/v1/gateway/usage-limits/:id/usage

Returns the current rolling usage and whether the threshold has been reached:

{
"data": {
"limitId": "lim_…",
"limitType": "tokens",
"threshold": "5000000",
"currentUsage": "3812044",
"timeWindow": "1 day",
"exceeded": false
}
}

Request size

ServiceLimit
Gateway proxy (LLM requests)100 MB per request body on Gate’s hosted gateway
Dashboard API (configuration calls)10 MB per request body

The gateway cap is an operator setting per deployment (GATEWAY_MAX_BODY_SIZE), not a fixed product number: Gate’s hosted gateway admits 100 MB, and a self-hosted gateway that leaves the variable unset falls back to 25 MB. Long agentic conversations that resend the whole thread, plus large tool-result blobs, are what approach it. Exceed the cap and the gateway returns HTTP 413 with code request_too_large and the enforced value in the body’s limit field, so a client can read the active ceiling instead of assuming one.


Data retention

Every request is recorded, and the different kinds of data Gate keeps have different lifetimes. Retention is not a plan feature: the readable-content window is the same for Free and Pro.

DataRetention
Readable content: request and response bodies, turn content, security-decision payloads90 days
Metrics: activity, cost, and token aggregatesKept for the life of the organization
Audit events and integrity checkpointsPermanent

The 90-day window is the platform default and can be overridden per organization, shorter or longer, by Gate operators; Enterprise agreements are where a different window is usually agreed. When readable content is reaped at the end of its window, the audit event itself (timestamp, model, cost, security outcome) is kept permanently and its inclusion proof keeps verifying. Only the readable content is deleted.


Rate-limit and usage-limit errors

HTTP statuscodeMeaning
429rate_limit_exceededPer-key or org-level sliding-window rate limit exceeded.
429usage_limit_exceededA configured rolling usage limit (cost / tokens / requests) was exceeded.
413request_too_largeRequest body exceeds the gateway’s configured cap. The enforced value is in the body’s limit field.
402insufficient_balancePrepaid balance too low to cover the estimated request cost.
429payg_reservedThe balance covers the request, but your other in-flight requests hold it. Retry after Retry-After.
503auth_unavailableGate could not check the API key right now. Not throttling and not a bad key. Retry after Retry-After.
402payg_disabledPaying through Gate is not enabled for this organization.
503pricing_unavailableNo pricing data exists for the requested model, so the request is refused rather than served for free.

For the full error taxonomy see Error handling.


  • Authentication: how paying through Gate vs your own keys are chosen per request.
  • Error handling: full error taxonomy and debugging tips.
  • Plans: which limits are a plan feature and which are not.