Rate Limiting

To ensure the stability and reliability of TapTree's services, we implement rate limiting on our API endpoints. This guide provides an overview of our rate limiting policies, details about rate limit responses and headers, and best practices for handling rate-limited requests.

Rate Limit Policies

TapTree enforces rate limits based on the API key you are using. Exceeding these limits will result in 429 Too Many Requests responses. Below are the current rate limit tiers:

  • Test API Keys: 100 requests per minute
  • Live API Keys: 3,000 requests per minute

Important: These limits are treated as maximum thresholds. Design your application to operate well within these limits to avoid unexpected interruptions.

If you anticipate higher traffic, contact TapTree support for a custom rate limit.

Responses and Headers

When you exceed the allowed number of requests, TapTree responds with a 429 Too Many Requests status code. Additionally, several headers provide detailed information about your current rate limit status.

Response Structure

{
  "status": 429,
  "type": "Too Many Requests",
  "detail": "Rate limit exceeded. Try again in 60 seconds.",
  "retry_after": "60"
}

Rate Limit Headers

The following headers are included in every API response:

HeaderDescription
x-ratelimit-limitThe maximum number of requests the client is allowed to make within the current time window.
x-ratelimit-remainingThe number of requests remaining for the client in the current time window.
x-ratelimit-resetThe number of seconds until the rate limit resets.
retry-afterIndicates how long the client should wait before making a new request (same value as x-ratelimit-reset).

Example Headers

HTTP/1.1 429 Too Many Requests
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
x-ratelimit-reset: 60
retry-after: 60
Content-Type: application/json

```json
{
  "status": 429,
  "type": "Too Many Requests",
  "detail": "Rate limit exceeded. Try again in 60 seconds.",
  "retry_after": "60"
}

Handling Rate Limits

Properly handling `429` responses ensures your application remains robust and provides a seamless user experience even under high load conditions.

1. Respect Rate Limit Headers

Use the information provided in rate limit headers to make informed decisions about request pacing.

async function handleRequest(url, options) {
  const response = await fetch(url, options);
  
  if (response.status === 429) {
    const retry_after = response.headers.get('retry-after');
    const reset = response.headers.get('x-ratelimit-reset');
    console.warn(`Rate limit exceeded. Retry after ${retry_after} seconds.`);
    // Implement retry logic here, such as waiting for retry_after seconds before retrying
  } else {
    // Handle successful response
  }
}

2. Implement Retry Mechanisms

When you receive a `429 Too Many Requests` response, implement a retry mechanism to attempt the request after a specified delay.

Exponential Backoff helps in gradually increasing the wait time between retries, reducing the likelihood of overwhelming the server.

const MAX_RETRIES = 5;

async function fetchWithRetry(url, options, retries = 0) {
  try {
    const response = await fetch(url, options);
    if (response.status === 429 && retries < MAX_RETRIES) {
      const retry_after = response.headers.get('retry-after') || 60; // Default to 60 seconds
      console.warn(`Rate limit exceeded. Retrying in ${retry_after} seconds.`);
      await new Promise(resolve => setTimeout(resolve, retry_after * 1000));
      return fetchWithRetry(url, options, retries + 1);
    }
    return response;
  } catch (error) {
    if (retries < MAX_RETRIES) {
      const delay = Math.pow(2, retries) * 1000; // Exponential backoff
      console.error(`Error fetching ${url}. Retrying in ${delay} ms.`);
      await new Promise(resolve => setTimeout(resolve, delay));
      return fetchWithRetry(url, options, retries + 1);
    }
    throw error;
  }
}

3. Optimize Request Rate

Ensure that your application does not exceed the rate limits by optimizing the frequency of API calls.

  • Batch Requests: Combine multiple operations into a single request when possible.
  • Caching: Cache responses to reduce the need for repeated requests.
  • Throttling: Control the rate at which requests are sent from the client side.

Preventing Exponential Backoff

While exponential backoff is effective, improper implementation can lead to resource exhaustion or degraded performance. Follow these best practices to mitigate potential issues.

Best Practices

  1. Set Maximum Retry Limits: Define a maximum number of retries to prevent infinite loops. For instance, limit retries to 5 attempts.

  2. Implement Jitter: Introduce randomness to the backoff intervals to avoid synchronized retry bursts.

  3. Monitor and Log Retries: Keep track of retry attempts to identify patterns or persistent issues.

  4. Graceful Degradation:: Design your application to handle prolonged rate limiting gracefully, such as by notifying users or reducing functionality temporarily.

  5. Client-Side Rate Limiting:: Implement client-side rate limiting algorithms like the Token Bucket to control the rate of outgoing requests proactively.

Was this page helpful?