Rate Limits
Each tenant has two rate limits, one for reads (query) and one for writes (ingest). A bulk import never uses up the budget your storefront prices against.
How a limit works
A limit is a token bucket with two numbers:
- Rate: how fast the bucket refills, in items per second.
- Burst: how many items the bucket holds, and so how many you can spend at once.
A full bucket lets you send a burst immediately. After that, you can sustain the rate. An idle bucket refills to the burst and no further. The limit applies to your tenant as a whole, whichever API node serves the request.
What a request costs
Limits count items, not HTTP requests, so batching does not get around them:
| Request | Dimension | Cost |
|---|---|---|
POST /price/query | query | number of SKUs in skus |
POST /price/batch, POST /article/batch, POST /pricelist/batch, and DELETE on them | ingest | number of elements in the array |
POST /fx/daily | ingest | number of rates |
POST /pricelist/query, POST /pricelist/search, POST /article/search | query | 1 |
any other GET | query | 1 |
| any other write | ingest | 1 |
The number of pricelists in a price query does not change its cost.
Headers
Every limited response carries:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | The burst: what a full bucket holds |
X-RateLimit-Remaining | Items left in the bucket (approximate) |
X-RateLimit-Reset | Unix time, in seconds, when the bucket will be full again |
When you hit the limit: 429
429 Too Many Requests means the bucket does not hold enough for this request right now. Retry-After gives the number of seconds until it does; wait that long and retry.
{
"status": 429,
"error": "Too Many Requests",
"message": "Rate limit exceeded for QUERY",
"retry_after": 2
}
When a request is too large: 413
A request costing more than the maximum items per request, or more than the burst, can never fit in the bucket. Such a request is refused with 413 Content Too Large before it spends anything. Retrying will not help; split the request instead.
{
"status": 413,
"error": "Payload Too Large",
"message": "This request costs 3000 items; at most 2500 are allowed per request. Split it into smaller requests.",
"max_items_per_request": 2500
}
Staying within the limit
- Send requests at the rate and keep the burst for spikes.
- On 429, wait for
Retry-Afterbefore sending the next request. Retrying in a tight loop only spends budget on refusals. - Size batches by
max_items_per_request, not by trial and error.