# Rate limits

> How Shoplazza REST API rate limits work: the per-app and per-store dimensions, the leaky bucket algorithm, the rate limit headers, and handling 429 responses.

## Shoplazza API rate limits

All Shoplazza APIs are rate-limited. The REST Admin API uses **request-based limits**: each request counts equally, regardless of how much data it returns.

The REST Admin API enforces limits across two dimensions:

* App/store: each app and store pair has an independent limit.
* Store: each store has an independent limit across requests.

For example: Each request is counted against both dimensions. For example, when App A calls Store 1, the request consumes capacity from the App A and Store 1 bucket, and also from the Store 1 bucket. The request succeeds only when both buckets have capacity.

| Current bucket state | Result |
| --- | --- |
| App A + Store 1 is `39/40`, and Store 1 is `79/80` | The request can run. After it is counted, the buckets become `40/40` and `80/80`. |
| App A + Store 1 is `40/40`, and Store 1 is `10/80` | The request is throttled because the app/store bucket is full. |
| App A + Store 1 is `10/40`, and Store 1 is `80/80` | The request is throttled because the store bucket is full. |

The default settings for the app/store dimension are:

* Bucket size: 40 requests per app/store
* Leak rate: 2 requests per second

The default settings for the store dimension are:

* Bucket size: 80 requests per store
* Leak rate: 20 requests per second

To avoid being throttled, follow these practices on the client side:

* Keep a separate request queue for each store. This prevents a burst for one store from delaying calls to another store.
* Limit the dispatch rate for each app/store pair to stay under the app/store leak rate.
* Track the combined request volume for each store so all apps or workers calling the same store stay under the store leak rate.
* Monitor the `X-Shoplazza-Shop-Api-Call-Limit` header on each response. When the value gets close to the bucket size, slow down before the bucket is full.
* Cache responses you can reuse, especially repeated reads for the same resource.
* When you receive a `429`, pause the affected queue and read the `Retry-After` header. Resume requests after the number of seconds it specifies.

## The leaky bucket algorithm

All Shoplazza APIs manage requests with a leaky bucket algorithm. This lets your app make bursts of requests over time, as long as it doesn't overflow the bucket. The metaphor works as follows:

* Each app has access to a “bucket” that holds a fixed number of “marbles” (for example, 40).
* Each API request tosses one marble into the bucket.
* The bucket leaks at a steady rate (for example, 2 marbles per second), freeing up space over time.
* If the bucket is full, requests fail with an error until the bucket leaks enough to make room.

## Rate limit headers

Use the `X-Shoplazza-Shop-Api-Call-Limit` header returned with each API response to see how many requests you’ve made against a store.

X-Shoplazza-Shop-Api-Call-Limit: 32/40

* 32: The current number of marbles in the bucket.
* 40: The maximum bucket size.

The count leaks down over time. For example, if the header shows 39/40 and you stop sending requests, after ten seconds it may show 19/40.

The `Retry-After` header specifies the number of seconds to wait before retrying after a **429 Too Many Requests** response.

## Handling 429 responses

When a request exceeds the rate limit, Shoplazza returns a **429 Too Many Requests** error along with a `Retry-After` header. Wait for the specified number of seconds before retrying. Any request made during this period is throttled.

X-Shoplazza-Shop-Api-Call-Limit: 40/40\
Retry-After: 2.0
