Dashboard

Rate limits

The request budgets that protect the Toggld API, and how to handle HTTP 429.

The Toggld API limits how many requests each IP address, workspace environment, and credential type can make in a time window. When you exceed a budget, the API returns HTTP 429 with a Retry-After header.

Limits

Every limit uses a window of 60 seconds. A window starts with the first accepted request.

BudgetLimitCounted per
All API requests1,200 requests per minuteIP address, before authentication
Failed authentication20 failures per minuteIP address. Counts missing credentials, invalid credentials, and denied roles (401 and 403).
Evaluation and sync with secret keys1,200 requests per minuteWorkspace environment. Covers OFREP evaluation and snapshot downloads (/ofrep/v1, /sync/v1).
Evaluation with public tokens120 requests per minuteIP address and environment
Evaluation with public tokens6,000 requests per minuteEnvironment, across all IP addresses
Telemetry120 requests per minuteEnvironment. Public tokens also count against the public token limits.
Management reads300 requests per minuteEnvironment
Management writes60 requests per minuteEnvironment
Analytics reads30 requests per minuteEnvironment

Notes:

  • A budget is shared by every credential of the environment. Two management keys for the same environment share one write budget. Dashboard activity in an environment counts toward the same budgets.
  • Secret-key evaluation and snapshot polling share one budget. Plan your poll interval and the number of clients so that they stay under it.
  • On the hosted API, the evaluation and sync limits are counted separately at each edge location. They are approximate, not a strict global quota.
  • IPv6 addresses in the same /64 network share one IP budget.
  • The MCP server has its own limits in addition to these.

Handle HTTP 429

HTTP/1.1 429 Too Many Requests
Retry-After: 12
Cache-Control: no-store
{ "code": "RATE_LIMITED", "message": "Too many requests. Try again later." }

When you receive HTTP 429:

  1. Read the Retry-After header. It is a positive number of seconds.
  2. Wait at least that long before you send the next request.
  3. Do not retry in a tight loop. Rejected requests do not extend the window, but they waste your time.

Browsers can read Retry-After on cross-origin OFREP responses.

The Node.js SDK does not read Retry-After. In remote mode, a rate-limited evaluation returns your fallback value with GENERAL and an errorMessage that names HTTP 429. In local mode, the SDK keeps its last snapshot and polls again later.

HTTP 503

If the rate limiter itself is unavailable, the API refuses protected requests with HTTP 503, Retry-After: 5, and this body:

{ "code": "RATE_LIMIT_UNAVAILABLE", "message": "Request limits are unavailable. Try again later." }

The API never lets requests through without a limit check. Health checks stay available.

Stay under the limits

  • Use local evaluation on long-lived servers. It needs one snapshot request per poll interval instead of one request per evaluation.
  • In browsers, call the bulk endpoint once per page load instead of one request per flag.
  • Reuse one SDK client per process.
  • Batch management changes, and avoid polling the Management API for changes.

On this page