Skip to main content

Rate Limiting Overview

Fetchin implements two types of rate limiting to ensure fair usage and system stability:
  1. Per-second rate limit: Configurable per plan (default: 20 requests per second)
  2. Monthly quota: Based on your plan (100 for Trial, custom for Enterprise)

Rate Limit Structure

Per-Second Limit

Plan-basedTrial: 20 requests/second Enterprise: Custom RPS

Monthly Quota

Plan-basedTrial: 1,000 credits/month Enterprise: Custom

Per-Second Rate Limit

Your per-second rate limit depends on your plan. Trial plans have a default of 20 requests per second, while Enterprise plans can have custom limits.

How It Works

  • Requests are counted using a sliding window algorithm
  • After exceeding your RPS limit, subsequent requests return 429
  • The limit is per API key and applies across all endpoints
  • Your specific RPS limit is visible in your dashboard

Example (with 20 RPS limit)

Second 1: 20 requests ✅ (all succeed)
Second 1: 21st request ❌ (429 error)
Second 2: 20 requests ✅ (window slides, all succeed)
Your RPS limit applies across ALL your requests. If you make 20 profile requests in one second (with a 20 RPS limit), you cannot make any posts requests until the window slides.

Monthly Quota Limiting

Total credits allowed per month based on your plan:
  • Trial Plan: 1,000 credits/month
  • Enterprise Plan: Custom limits

How It Works

  • Each successful API request consumes credits from your monthly quota
  • Failed requests (errors) also count toward quota
  • Quota resets on your renewal date (monthly anniversary of signup)
  • Unused credits do NOT carry over to next month

Handling Rate Limit Errors

429 Too Many Requests

You’ll receive this error in two scenarios: Per-second limit exceeded:
{
  "error": "Rate limit exceeded. Try again later."
}
Monthly quota exceeded:
{
  "error": "Quota exceeded. Upgrade your plan or wait for renewal."
}

Response Headers

Each API response includes rate limit headers:
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1704067201
  • X-RateLimit-Limit: Requests allowed per second (20)
  • X-RateLimit-Remaining: Requests remaining this second
  • X-RateLimit-Reset: Unix timestamp when limit resets
Rate limit headers show per-second limits. Check your dashboard for both your RPS limit and monthly quota information.
Enterprise plans can request custom RPS limits. Contact sales if you need higher throughput for your application.

Best Practices

1. Respect Your RPS Limit

Space out your requests to stay under your rate limit (default: 20 per second for Trial plans):
async function fetchMultipleProfiles(profileUrls, apiKey) {
  const delay = 50; // 50ms = 20 req/s max
  const results = [];
  
  for (const url of profileUrls) {
    const response = await fetch(
      `https://api.fetchin.io/api/v1/profile?profileUrlOrUrn=${url}`,
      { headers: { 'X-API-Key': apiKey } }
    );
    
    results.push(await response.json());
    
    await new Promise(resolve => setTimeout(resolve, delay));
  }
  
  return results;
}

2. Implement Retry Logic with Backoff

async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);
    
    if (response.status === 429) {
      const waitTime = Math.pow(2, i) * 1000;
      await new Promise(resolve => setTimeout(resolve, waitTime));
      continue;
    }
    
    return response;
  }
  
  throw new Error('Max retries exceeded');
}

3. Use Concurrency Control

Limit concurrent requests to respect the rate limit:
class RateLimiter {
  constructor(maxPerSecond = 20) {
    this.maxPerSecond = maxPerSecond;
    this.queue = [];
    this.processing = 0;
    this.lastReset = Date.now();
    this.requestsThisSecond = 0;
  }
  
  async add(fn) {
    while (this.requestsThisSecond >= this.maxPerSecond) {
      const now = Date.now();
      const timeSinceReset = now - this.lastReset;
      
      if (timeSinceReset >= 1000) {
        this.requestsThisSecond = 0;
        this.lastReset = now;
      } else {
        await new Promise(resolve => 
          setTimeout(resolve, 1000 - timeSinceReset)
        );
      }
    }
    
    this.requestsThisSecond++;
    return await fn();
  }
}

const limiter = new RateLimiter(20);

await limiter.add(() => fetchProfile(url1));
await limiter.add(() => fetchProfile(url2));

4. Check Quota Before Bulk Operations

Before processing large batches:
  1. Check remaining quota in dashboard
  2. Calculate how many requests you need
  3. Process in chunks if quota is low

3. Queue Requests

For high-volume applications, implement a request queue:
class RequestQueue {
  constructor(maxConcurrent = 5) {
    this.maxConcurrent = maxConcurrent;
    this.running = 0;
    this.queue = [];
  }
  
  async add(fn) {
    if (this.running >= this.maxConcurrent) {
      await new Promise(resolve => this.queue.push(resolve));
    }
    
    this.running++;
    
    try {
      return await fn();
    } finally {
      this.running--;
      const resolve = this.queue.shift();
      if (resolve) resolve();
    }
  }
}

5. Cache Aggressively

Store results to avoid repeat requests:
const cache = new Map();

async function getCachedProfile(profileUrl, apiKey) {
  if (cache.has(profileUrl)) {
    return cache.get(profileUrl);
  }
  
  const response = await fetch(
    `https://api.fetchin.io/api/v1/profile?profileUrlOrUrn=${profileUrl}`,
    { headers: { 'X-API-Key': apiKey } }
  );
  
  const data = await response.json();
  cache.set(profileUrl, data);
  
  return data;
}

Common Scenarios

Batch Processing

Processing 100 profiles at 20 req/s:
100 profiles ÷ 20 req/s = 5 seconds minimum
Add buffer time for network latency and processing:
Estimated time: 6-8 seconds

Real-Time Applications

For real-time applications making frequent requests:
  1. Implement request queuing
  2. Use websockets for updates when possible
  3. Cache frequently accessed data
  4. Batch multiple data points into single requests
If you need higher rate limits for your use case, contact sales for an Enterprise plan with custom limits.

Error Responses

429 Too Many Requests (Per-Second)

{
  "error": "Rate limit exceeded. Try again later."
}
Cause: Exceeded your per-second rate limit Solution:
  • Wait 1 second before retrying
  • Implement request spacing based on your RPS limit
  • Use rate limiting library

429 Too Many Requests (Monthly Quota)

{
  "error": "Quota exceeded. Upgrade your plan or wait for renewal."
}
Cause: Monthly quota depleted Solution:
  • Wait for quota renewal
  • Upgrade to higher quota plan
  • Purchase additional credits (coming soon)

Monitoring

Track your rate limit compliance:
  • Dashboard - View daily usage patterns and monthly quota
  • Error rate - Monitor 429 errors (both types)
  • Response headers - Check X-RateLimit-* headers in responses
  • Success rate - Ensure efficient request usage
Both per-second rate limit violations AND monthly quota exceedances count as failed requests and still consume your monthly quota.