Skip to content

API Rate Limits

Rate limiting policies and best practices for Lager Guru API.

Overview

Lager Guru implements rate limiting to ensure fair usage, prevent abuse, and maintain system stability. All API endpoints are subject to rate limits based on your plan tier.

Rate Limit Types

Soft Limits

Soft limits are recommended thresholds. Exceeding them may result in:

  • Slower response times
  • Throttling warnings
  • Performance degradation

Standard Endpoints: 1000 requests per minute
Authentication Endpoints: 60 requests per minute
Webhook Endpoints: 500 requests per minute

Hard Limits

Hard limits are enforced boundaries. Exceeding them results in:

  • 429 Too Many Requests responses
  • Temporary blocking
  • Required retry delays

Standard Endpoints: 2000 requests per minute (burst: 400 per 10 seconds)
Authentication Endpoints: 120 requests per minute (burst: 20 per 10 seconds)
Webhook Endpoints: 1000 requests per minute (burst: 200 per 10 seconds)

Burst Usage

Burst limits allow short-term spikes in usage:

  • Standard: 400 requests per 10-second window
  • Authentication: 20 requests per 10-second window
  • Webhook: 200 requests per 10-second window

Burst limits reset every 10 seconds, allowing for rapid initial requests followed by steady-state usage.

Rate Limit Headers

All API responses include rate limit information:

http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 850
X-RateLimit-Reset: 1640995200
X-RateLimit-Used: 150

Header Descriptions

  • X-RateLimit-Limit: Maximum requests allowed in the current window
  • X-RateLimit-Remaining: Remaining requests in current window
  • X-RateLimit-Reset: Unix timestamp when the limit resets
  • X-RateLimit-Used: Number of requests used in current window

Rate Limit Responses

429 Too Many Requests

When rate limit is exceeded:

http
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60

{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Please retry after 60 seconds.",
  "retry_after": 60,
  "limit": 1000,
  "remaining": 0,
  "reset_at": "2025-01-15T10:30:00Z"
}

The Retry-After header indicates seconds to wait before retrying.

Cursor-Based Pagination

For large datasets, use cursor-based pagination:

typescript
// First request
const response = await fetch('/api/orders?limit=50');
const { data, next_cursor } = await response.json();

// Subsequent requests
const nextResponse = await fetch(`/api/orders?limit=50&cursor=${next_cursor}`);

Offset-Based Pagination

For smaller datasets, offset pagination is acceptable:

typescript
// Page 1
const page1 = await fetch('/api/orders?page=1&limit=50');

// Page 2
const page2 = await fetch('/api/orders?page=2&limit=50');

Best Practices

  1. Use appropriate page sizes: 50-100 items per page
  2. Cache results: Store paginated results to reduce API calls
  3. Batch operations: Combine multiple operations when possible
  4. Monitor headers: Always check X-RateLimit-Remaining

Per-Tenant Rate Limits

In multi-tenant deployments, rate limits apply per tenant:

  • Each tenant has independent rate limit quotas
  • Limits are enforced at the tenant level
  • Super admins have higher limits across all tenants

Example

typescript
// Tenant A: 1000 requests/minute
// Tenant B: 1000 requests/minute (independent)
// Both tenants can use their full quota simultaneously

Edge Functions Rate Limits

Edge Functions have separate rate limiting:

  • Standard Functions: 1000 invocations per minute
  • Background Functions: 500 invocations per minute
  • Webhook Functions: 200 invocations per minute

Edge Function Best Practices

  1. Batch processing: Process multiple items in a single invocation
  2. Caching: Cache results to avoid redundant invocations
  3. Error handling: Implement retry logic with exponential backoff
  4. Monitoring: Track invocation counts and errors

Handling Rate Limits

Exponential Backoff

typescript
async function requestWithRetry(url: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);
      
      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        const delay = Math.min(retryAfter * 1000, Math.pow(2, i) * 1000);
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}

Rate Limit Monitoring

typescript
function checkRateLimit(headers: Headers) {
  const remaining = parseInt(headers.get('X-RateLimit-Remaining') || '0');
  const limit = parseInt(headers.get('X-RateLimit-Limit') || '1000');
  
  if (remaining < limit * 0.1) {
    console.warn('Rate limit approaching. Remaining:', remaining);
    // Implement throttling or user notification
  }
  
  return {
    remaining,
    limit,
    resetAt: new Date(parseInt(headers.get('X-RateLimit-Reset') || '0') * 1000)
  };
}

Enterprise Limits

Enterprise plans include higher rate limits:

  • API Endpoints: 10,000 requests per minute
  • Database Queries: 50,000 queries per minute
  • Webhooks: 5,000 requests per minute
  • Edge Functions: 5,000 invocations per minute
  • Custom Limits: Available upon request

Best Practices Summary

  1. Monitor Headers: Always check rate limit headers in responses
  2. Implement Backoff: Use exponential backoff when rate limited
  3. Cache Responses: Cache frequently accessed data
  4. Batch Requests: Combine multiple operations when possible
  5. Use Webhooks: Prefer webhooks over polling
  6. Paginate Efficiently: Use appropriate pagination strategies
  7. Handle Errors Gracefully: Implement proper error handling

Публикувано под търговска лицензия