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 Requestsresponses- 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:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 850
X-RateLimit-Reset: 1640995200
X-RateLimit-Used: 150Header 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/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.
Recommended Pagination Patterns
Cursor-Based Pagination
For large datasets, use cursor-based pagination:
// 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:
// 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
- Use appropriate page sizes: 50-100 items per page
- Cache results: Store paginated results to reduce API calls
- Batch operations: Combine multiple operations when possible
- 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
// Tenant A: 1000 requests/minute
// Tenant B: 1000 requests/minute (independent)
// Both tenants can use their full quota simultaneouslyEdge 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
- Batch processing: Process multiple items in a single invocation
- Caching: Cache results to avoid redundant invocations
- Error handling: Implement retry logic with exponential backoff
- Monitoring: Track invocation counts and errors
Handling Rate Limits
Exponential Backoff
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
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
- Monitor Headers: Always check rate limit headers in responses
- Implement Backoff: Use exponential backoff when rate limited
- Cache Responses: Cache frequently accessed data
- Batch Requests: Combine multiple operations when possible
- Use Webhooks: Prefer webhooks over polling
- Paginate Efficiently: Use appropriate pagination strategies
- Handle Errors Gracefully: Implement proper error handling
Related Documentation
- API Reference - Complete API documentation
- Authentication - Authentication guide
- Development Rate Limits - Detailed rate limit documentation