Erros de limite de taxa

Última atualização: há 3 meses

Se você vir 429 Too Many Requests, você está acessando a API com muita frequência. Veja como lidar com isso corretamente.

O erro

HTTP 429 Too Many Requests
{
  "error": "Limit exceed."
}

Por que isso acontece

Os limites de taxa protegem a API contra uso excessivo:

  • Muitas requisições em pouco tempo

  • Consulta frequente (polling) agressiva ou scraping

  • Sem intervalo entre as requisições

  • Requisições simultâneas sem controle de taxa (throttling)

Estratégia de backoff exponencial

A melhor forma de lidar com limites de taxa é usar backoff exponencial — espere mais tempo após cada nova tentativa:

async function fetchWithBackoff(url, options, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        const waitTime = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s, 8s, 16s
        console.log(`Rate limited. Waiting ${waitTime}ms before retry ${attempt + 1}/${maxRetries}`);
        
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      
      return await response.json();
      
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
    }
  }
  
  throw new Error('Max retries exceeded');
}

Prevenindo limites de taxa

Adicione atrasos entre as requisições:

// Ruim: requisições em sequência rápida
for (const id of mediaIds) {
  await api.getResource(id); // Sem atraso
}
// Bom: requisições com controle de taxa
for (const id of mediaIds) {
  await api.getResource(id);
  await sleep(500); // atraso de 500ms
}

Faça operações em lote:

// Processar em lotes de 10 com atrasos
const batchSize = 10;
for (let i = 0; i < mediaIds.length; i += batchSize) {
  const batch = mediaIds.slice(i, i + batchSize);
  await Promise.all(batch.map(id => api.getResource(id)));
  
  if (i + batchSize < mediaIds.length) {
    await sleep(2000); // 2s entre lotes
  }
}

Armazene respostas em cache:

const cache = new Map();
async function getCachedResource(mediaId) {
  if (cache.has(mediaId)) {
    return cache.get(mediaId);
  }
  
  const data = await api.getResource(mediaId);
  cache.set(mediaId, data);
  return data;
}

O que NÃO fazer

  • ❌ Tentar novamente imediatamente sem atraso

  • ❌ Fazer requisições paralelas sem limite

  • ❌ Ignorar erros 429

  • ❌ Usar atrasos fixos e curtos (use sempre backoff exponencial)

Se os problemas persistirem

Entre em contato com o suporte ao desenvolvedor se você realmente precisar de limites de taxa mais altos para o seu caso de uso. Forneça detalhes sobre:

  • Sua aplicação e seu caso de uso

  • Volume esperado de requisições

  • Implementação atual (com backoff)

Este artigo foi útil?