Skip to content

Rate Limits & Quotas

BVE Gateway enforces per-key rate limits using a Cloudflare Durable Object (ApiKeyLimiter). Each API key gets its own DO instance, so limits are applied independently per key.

LimitScopeDefaultConfigurableEnforced
RPMPer minute60Yes (per key)Yes
RPDPer day10,000Yes (per key)Yes
Monthly requestsPer calendar monthNoneYes (per key)Yes
Monthly tokensPer calendar monthNoneYes (per key)Stored only

RPM, RPD, and monthly request limits are enforced by the ApiKeyLimiter Durable Object. The monthly_token_limit field is stored in D1 but is not currently enforced — it exists for future use.

Defaults are set at key creation and can be customized via the rpm_limit, rpd_limit, monthly_limit, and monthly_token_limit fields in POST /admin/api-keys.

  1. On each request, the auth middleware resolves the API key from D1.
  2. The quota middleware calls ApiKeyLimiter.checkAndIncrement() on the DO instance for that key.
  3. If any limit is exceeded, the request is rejected with 429.
  4. If the DO call fails, the request is allowed (fail-open) to avoid blocking legitimate traffic.
WindowResets
MinuteRolling — each DO instance has a resetAt timestamp set 60 seconds ahead at window start
DayUTC midnight
MonthFirst day of the next UTC month

When a limit is exceeded, the response is:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"error": {
"message": "Rate limit exceeded: requests per minute",
"type": "rate_limit_error",
"code": "rate_limit_exceeded"
}
}

Possible error messages:

  • "Rate limit exceeded: requests per minute" — RPM limit hit
  • "Rate limit exceeded: requests per day" — RPD limit hit
  • "Monthly request limit exceeded" — monthly request cap hit

In addition to per-key limits, the Worker has global request caps configured in wrangler.jsonc:

ThresholdValue
Soft cap8,500,000 req/month
Hard cap9,500,000 req/month

These are environment variable values (MONTHLY_WORKER_REQUEST_SOFT_CAP, MONTHLY_WORKER_REQUEST_HARD_CAP) and are not automatically enforced — they are available to monitoring/alerting logic.

Checking remaining quota (response headers)

Section titled “Checking remaining quota (response headers)”

If Fuelix includes quota headers in its response, they are forwarded:

HeaderDescription
x-quota-allowedWhether quota was allowed (from Fuelix)
x-quota-availableRemaining quota (from Fuelix)
x-quota-resetQuota reset time (from Fuelix)

BVE Gateway itself does not yet add remaining-quota headers to responses.