Skip to main content

Overview

The TrackGeek API uses a dual-throttler approach to rate limit requests. Different limits apply to read operations (GET) and write operations (POST, PUT, PATCH, DELETE) to optimize for typical usage patterns.

Configuration

Rate limiting is configured globally using NestJS Throttler with the following settings:
ThrottlerModule.forRoot({
  throttlers: [
    { name: "read", ttl: 60_000, limit: 30, blockDuration: 300_000 },
    { name: "write", ttl: 60_000, limit: 5, blockDuration: 300_000 },
  ],
})

Read Throttler

Applies to all GET requests:
  • Limit: 30 requests
  • Time Window: 60 seconds (60,000 milliseconds)
  • Block Duration: 5 minutes (300,000 milliseconds)

Write Throttler

Applies to POST, PUT, PATCH, and DELETE requests:
  • Limit: 5 requests
  • Time Window: 60 seconds (60,000 milliseconds)
  • Block Duration: 5 minutes (300,000 milliseconds)
If you exceed the rate limit, your IP address will be blocked for 5 minutes. During this time, all requests will be rejected with a 429 status code.

How It Works

The API uses a custom HttpThrottlerGuard that automatically determines which throttler to apply based on the HTTP method:
const WRITE_METHODS = ["POST", "PUT", "PATCH", "DELETE"];

protected async handleRequest(requestProps: ThrottlerRequest): Promise<boolean> {
  const { context, throttler } = requestProps;
  
  const request = context.switchToHttp().getRequest<{ method: string }>();
  const method = request.method?.toUpperCase();
  const isWriteMethod = WRITE_METHODS.includes(method);
  
  if (throttler.name === "read" && isWriteMethod) return true;
  if (throttler.name === "write" && !isWriteMethod) return true;
  
  return super.handleRequest(requestProps);
}

Rate Limit Response

When you exceed the rate limit, the API returns:
{
  "code": "RATE_LIMIT_EXCEEDED",
  "status": 429
}

Best Practices

Optimize Your Requests: Use pagination to fetch data in smaller chunks rather than requesting large datasets at once.

Rate Limit Strategy

  1. Cache responses on your client to minimize redundant API calls
  2. Batch operations when possible to stay within write limits
  3. Implement exponential backoff when you receive 429 responses
  4. Monitor your usage to stay well below the limits

Example: Handling Rate Limits

async function fetchWithRetry(url: string, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url);
      
      if (response.status === 429) {
        const retryAfter = 300; // 5 minutes in seconds
        console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}
The block duration starts from the time you first exceed the limit, not from your last request. Wait the full 5 minutes before retrying.

Rate Limit Headers

The API does not currently expose rate limit information in response headers. Monitor your request patterns and implement client-side tracking to stay within limits.

Build docs developers (and LLMs) love