Fabric documentation

Handling rate limits

The four budgets, the headers on every response, and what to do on a 429.

Rate limits apply per organization, not per key. A second key shares the same budgets as the first, so it adds no capacity.

The budgets

Each operation belongs to one of four cost classes, and each class has its own budget. Reading a page of products and starting an enrichment run are counted separately.

ClassBurstSustainedApplies to
Read20/s600/minEvery GET
Write10/s300/minValue edits, definitions, views, lists, webhooks
Job2/s100/hourImports, exports, AI helpers, publish runs, attribute scope moves
Spend1/s20/hourEnrichment runs and re-enrichment

Burst and sustained limits apply separately. A client that stays under the burst limit can still go over the sustained limit.

The headers

Every response reports the state of the budget it counted against, so you can see how much is left before you reach a 429.

RateLimit-Limit: 600
RateLimit-Remaining: 594
RateLimit-Reset: 41

RateLimit-Reset is the number of seconds until the window resets.

Handle a 429

A 429 adds Retry-After, in seconds. Wait that long. The value is exact, not an estimate.

{
  "code": "rate_limited",
  "status": 429,
  "title": "Too many requests",
  "detail": "Over the read budget for this organization. Retry in 12s."
}

Retry on 429, 503 and a network failure. Do not retry a 400, 403, 404 or 422: the same request fails the same way next time, and every attempt counts against your budget.

Throttling comes before the scope check

A 429 can arrive on a request that would also fail its permission check. Wait and retry first, then read the error the retry returns.