Rate Limiting

Understand Sematryx rate limits and learn how to handle them gracefully in your applications.

Rate Limits by Tier

Rate limits are applied per minute and vary by plan:

TierRequests/MinuteBurst LimitMonthly Solves
Free1015100
Pay-as-you-go6090Unlimited

Burst limits allow temporary spikes above the sustained rate. See Billing & Usage for monthly optimization limits.

Rate Limit Headers

Every API response includes rate limit information in the headers:

Rate limit response headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1640995200
X-RateLimit-Window: 60

Header Fields

  • X-RateLimit-Limit: Maximum requests allowed in the window
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: Unix timestamp when the window resets
  • X-RateLimit-Window: Window duration in seconds

Handling Rate Limits

When you exceed the rate limit, you'll receive a 429 Too Many Requests response. Always check rate limit headers and implement retry logic:

Python Example

Rate limit handling in Python
import time
import requests

def make_request_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(url, headers=headers)
        
        if response.status_code == 429:
            reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
            wait_time = max(reset_time - time.time(), 1)
            print(f'Rate limit exceeded. Waiting {wait_time} seconds...')
            time.sleep(wait_time)
            continue
        
        return response
    
    raise Exception('Max retries exceeded')

JavaScript Example

Rate limit handling in JavaScript
async function makeRequestWithRetry(url, headers, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, { method: 'POST', headers })
    
    if (response.status === 429) {
      const resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0')
      const waitTime = Math.max(resetTime - Date.now() / 1000, 1)
      console.log(`Rate limit exceeded. Waiting ${waitTime} seconds...`)
      await new Promise(resolve => setTimeout(resolve, waitTime * 1000))
      continue
    }
    
    return response
  }
  
  throw new Error('Max retries exceeded')
}

Exponential Backoff

For more robust rate limit handling, implement exponential backoff with jitter:

Exponential backoff implementation
import time
import random

def exponential_backoff(attempt, base_delay=1, max_delay=60):
    """Calculate exponential backoff delay with jitter"""
    delay = min(base_delay * (2 ** attempt), max_delay)
    jitter = random.uniform(0, delay * 0.1)
    return delay + jitter

# Usage
for attempt in range(max_retries):
    try:
        response = make_request()
        break
    except RateLimitError:
        wait_time = exponential_backoff(attempt)
        time.sleep(wait_time)

Benefits

  • • Prevents thundering herd problems
  • • Reduces server load during high traffic
  • • More efficient use of available rate limit
  • • Jitter prevents synchronized retries

Best Practices

✓ Do

  • • Monitor rate limit headers
  • • Implement exponential backoff
  • • Cache results when possible
  • • Batch requests when available
  • • Respect the reset time

✗ Don't

  • • Ignore 429 status codes
  • • Retry immediately without waiting
  • • Make unnecessary requests
  • • Exceed limits intentionally
  • • Spin in tight retry loops

Increasing Rate Limits

Need higher rate limits? You have options:

Upgrade to Pay-as-you-go

Pay-as-you-go tier offers 6x the rate limit of Free tier with unlimited monthly solves.

View plans →

High-Volume Needs

Need higher rate limits? Contact us at hello@sematryx.com to discuss your requirements.