Rate Limiting
This document describes the rate limiting behavior of the remberg API.
Overview
To ensure fair usage and maintain service stability, all API endpoints are subject to rate limiting. When the rate limit is exceeded, the API will respond with HTTP status code 429 Too Many Requests.
Rate Limit Rules
The API enforces two separate rate limits that work together: a burst limit to prevent sudden spikes and a base limit for sustained load.
As a rule-of thumb: configure your integrations to not send more than 5 requests per second to stay below the limits.
Limit Configuration
| Throttler | Request Limit | Time Window | Purpose |
|---|---|---|---|
| Burst | 10 requests | 1 second | Prevents sudden request spikes |
| Base | 25 requests | 5 seconds | Controls sustained request rate |
Both limits use a sliding window algorithm and are enforced simultaneously. A request is rate-limited if it exceeds either limit.
How the Dual Limits Work Together
The burst limit prevents short, intense spikes while the base limit ensures fair usage over longer periods.
Example scenario:
- You send 10 requests instantly → all succeed (burst limit reached)
- You send 1 more request immediately → 429 (burst limit exceeded)
- You wait 1 second, then send 10 more → all succeed
- You continue this pattern → after 25 requests in 5 seconds, you hit the base limit
- Even if burst limit has capacity, base limit blocks further requests until the 5-second window slides
Key Behaviors
-
Per-User Limiting Rate limits are applied individually per authenticated user. Each user has their own rate limit buckets, meaning one user's activity does not affect another user's available quota.
-
Per-Endpoint Limiting Rate limits are tracked separately for each API endpoint. Requests to
/v1/contactsdo not count against the limit for/v1/assets, and vice versa. This allows you to make concurrent requests to different endpoints without them interfering with each other. -
Sliding Window Both rate limits use a sliding window algorithm. The system continuously tracks requests over the past N seconds (1s for burst, 5s for base), rather than resetting at fixed intervals.
-
429 Responses Count Against the Limit Important: Requests that receive a
429 Too Many Requestsresponse also count against the rate limit. This prevents retry storms from immediately succeeding. If you receive a 429, wait for the time indicated in theRetry-After-*header before retrying.
Response Headers
The API includes rate limit information in response headers. The headers differ between successful and rate-limited responses.
Headers on Non-Rate-Limited Responses (≠429)
Since there are two throttlers, each provides its own set of headers with a suffix indicating the throttler name:
| Header | Description |
|---|---|
X-RateLimit-Limit-Base | Maximum requests allowed in the base window (25) |
X-RateLimit-Remaining-Base | Requests remaining in the current base window |
X-RateLimit-Reset-Base | Seconds until the base window resets |
X-RateLimit-Limit-Burst | Maximum requests allowed in the burst window (10) |
X-RateLimit-Remaining-Burst | Requests remaining in the current burst window |
X-RateLimit-Reset-Burst | Seconds until the burst window resets |
Headers on Rate Limited Responses (429)
| Header | Description |
|---|---|
Retry-After-Base | Seconds to wait (if base limit triggered) |
Retry-After-Burst | Seconds to wait (if burst limit triggered) |
Note: The
X-RateLimit-*headers are only present on successful responses. When rate limited, only theRetry-After-*header for the triggered throttler is included.
Example Successful Response
HTTP 200 OK
X-RateLimit-Limit-Base: 25
X-RateLimit-Remaining-Base: 24
X-RateLimit-Reset-Base: 5
X-RateLimit-Limit-Burst: 10
X-RateLimit-Remaining-Burst: 9
X-RateLimit-Reset-Burst: 1
Content-Type: application/jsonExample Rate Limited Response (Burst Limit)
HTTP 429 Too Many Requests
Retry-After-Burst: 1
Content-Type: application/json
{
"statusCode": 429,
"message": "Too Many Requests"
}Example Rate Limited Response (Base Limit)
HTTP 429 Too Many Requests
Retry-After-Base: 5
Content-Type: application/json
{
"statusCode": 429,
"message": "Too Many Requests"
}Best Practices
Implement Exponential Backoff
When receiving a 429 response, implement exponential backoff with jitter, waiting at least Retry-After-* seconds before retrying.
Spread Requests Over Time
Instead of sending bursts of requests, spread them evenly:
// Instead of this (burst):
await Promise.all(items.map((item) => api.update(item)));
// Do this (throttled):
for (const item of items) {
await api.update(item);
await new Promise((resolve) => setTimeout(resolve, 250)); // 4 req/s stays under both limits
}Tip: Sending requests at 4-5 per second keeps you safely under both the burst limit (10/s) and the base limit (25/5s = 5/s average).
Monitor for 429 Responses
Log and monitor 429 responses in your application to identify integration issues before they impact your workflows.
Summary
| Aspect | Burst Throttler | Base Throttler |
|---|---|---|
| Limit | 10 requests per 1 second | 25 requests per 5 seconds |
| Purpose | Prevent sudden spikes | Control sustained load |
| Scope | Per user, per endpoint | Per user, per endpoint |
| Window | Sliding (1-second lookback) | Sliding (5-second lookback) |
| 429 counting | Yes, counts against limit | Yes, counts against limit |
| Recovery | Wait for Retry-After-Burst | Wait for Retry-After-Base |
Both limits are enforced simultaneously. A request is blocked if it exceeds either limit.
Updated 4 days ago
