Skip to content

Limites de Taxa

Visão Geral

O NetFind.io implementa rate limiting para garantir uso justo e estabilidade do sistema.

Limites Atuais

EndpointRequisições/minBurst
/api/search-and-scrape6010
/api/search-startpage305
/v1/search/hybrid6010

INFO

Os limites de taxa são aplicados por endereço IP.

Headers de Resposta

Informações de rate limit são incluídas nos headers de resposta:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1699123456
HeaderDescrição
X-RateLimit-LimitMáximo de requisições por janela
X-RateLimit-RemainingRequisições restantes na janela atual
X-RateLimit-ResetTimestamp Unix quando o limite reseta

Limite Excedido

Quando o rate limit é excedido, você receberá:

json
{
  "error": "Limite de taxa excedido",
  "detail": "Muitas requisições. Por favor aguarde antes de tentar novamente.",
  "retryAfter": 30
}

Status Code: 429 Too Many Requests

Tratando Rate Limits

Exemplo JavaScript

javascript
async function searchWithRateLimitHandling(query) {
  const response = await fetch(`/api/search-and-scrape?q=${encodeURIComponent(query)}`);

  if (response.status === 429) {
    const data = await response.json();
    const retryAfter = data.retryAfter || 30;

    console.log(`Rate limited. Tentando novamente em ${retryAfter}s`);
    await new Promise(r => setTimeout(r, retryAfter * 1000));

    return searchWithRateLimitHandling(query);
  }

  return response.json();
}

Com Exponential Backoff

javascript
class RateLimitedClient {
  constructor() {
    this.minDelay = 100;  // ms
    this.maxDelay = 60000; // 1 minuto
    this.currentDelay = this.minDelay;
  }

  async search(query) {
    // Aplica delay atual
    await new Promise(r => setTimeout(r, this.currentDelay));

    const response = await fetch(`/api/search-and-scrape?q=${encodeURIComponent(query)}`);

    if (response.status === 429) {
      // Aumenta delay exponencialmente
      this.currentDelay = Math.min(this.currentDelay * 2, this.maxDelay);
      return this.search(query);
    }

    // Sucesso - reduz delay
    this.currentDelay = Math.max(this.currentDelay / 2, this.minDelay);
    return response.json();
  }
}

Abordagem com Fila

Para processamento em lote:

javascript
class SearchQueue {
  constructor(requestsPerSecond = 1) {
    this.queue = [];
    this.processing = false;
    this.interval = 1000 / requestsPerSecond;
  }

  async add(query) {
    return new Promise((resolve, reject) => {
      this.queue.push({ query, resolve, reject });
      this.process();
    });
  }

  async process() {
    if (this.processing) return;
    this.processing = true;

    while (this.queue.length > 0) {
      const { query, resolve, reject } = this.queue.shift();

      try {
        const response = await fetch(`/api/search-and-scrape?q=${encodeURIComponent(query)}`);
        resolve(await response.json());
      } catch (error) {
        reject(error);
      }

      await new Promise(r => setTimeout(r, this.interval));
    }

    this.processing = false;
  }
}

// Uso
const queue = new SearchQueue(1); // 1 requisição por segundo

const results = await Promise.all([
  queue.add('query 1'),
  queue.add('query 2'),
  queue.add('query 3')
]);

Boas Práticas

1. Implemente Cache

Reduza chamadas à API com cache de resultados:

javascript
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos

async function cachedSearch(query) {
  const key = query.toLowerCase();
  const cached = cache.get(key);

  if (cached && Date.now() - cached.time < CACHE_TTL) {
    return cached.data;
  }

  const data = await search(query);
  cache.set(key, { data, time: Date.now() });
  return data;
}

2. Agrupe Requisições

Em vez de muitas requisições pequenas, use limits maiores:

javascript
// Em vez de 10 requisições com limit=5
// Faça 1 requisição com limit=50
const results = await search(query, { limit: 50 });

3. Use Debouncing

Para interfaces de busca enquanto digita:

javascript
function debounce(fn, delay) {
  let timeout;
  return (...args) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => fn(...args), delay);
  };
}

const debouncedSearch = debounce(async (query) => {
  const results = await search(query);
  updateUI(results);
}, 300);

// Chama a cada tecla - só executa após 300ms de pausa
input.addEventListener('input', (e) => debouncedSearch(e.target.value));

4. Monitore o Uso

Acompanhe seu uso da API para ficar dentro dos limites:

javascript
let requestCount = 0;
const windowStart = Date.now();

async function trackedSearch(query) {
  requestCount++;

  const elapsed = (Date.now() - windowStart) / 1000 / 60; // minutos
  const rate = requestCount / elapsed;

  if (rate > 50) {
    console.warn(`Alta taxa de requisições: ${rate.toFixed(1)}/min`);
  }

  return search(query);
}

Aumentando Limites

Para limites de taxa mais altos, entre em contato conosco com seu caso de uso:

  • Volume esperado de requisições
  • Tipo de aplicação
  • Estratégia de cache implementada

Tiers mais altos estarão disponíveis com autenticação via API key em releases futuros.

Feito com VitePress