Errores de límite de tasa

Última actualización: hace 3 meses

Si ves 429 Too Many Requests, estás accediendo a la API con demasiada frecuencia. Aquí está cómo manejarlo correctamente.

El error

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

Por qué sucede esto

Los límites de tasa protegen la API del uso excesivo:

  • Demasiadas peticiones en poco tiempo

  • Polling o scraping agresivo

  • Sin retraso entre peticiones

  • Peticiones concurrentes sin limitación

Estrategia de retroceso exponencial

La mejor manera de manejar límites de tasa es el retroceso exponencial - espera más tiempo después de cada reintento:

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(`Límite de tasa. Esperando ${waitTime}ms antes del reintento ${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('Reintentos máximos excedidos');
}

Prevenir límites de tasa

Añade retrasos entre peticiones:

// Mal: Peticiones rápidas consecutivas
for (const id of mediaIds) {
  await api.getResource(id); // Sin retraso
}
// Bien: Peticiones con limitación
for (const id of mediaIds) {
  await api.getResource(id);
  await sleep(500); // 500ms de retraso
}

Agrupa tus operaciones:

// Procesar en lotes de 10 con retrasos
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
  }
}

Cachea respuestas:

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;
}

Qué NO hacer

  • ❌ Reintentar inmediatamente sin retraso

  • ❌ Hacer peticiones paralelas sin límite

  • ❌ Ignorar errores 429

  • ❌ Usar retrasos fijos cortos (siempre usa retroceso exponencial)

Si los problemas persisten

Contacta con soporte para desarrolladores si legítimamente necesitas límites de tasa más altos para tu caso de uso. Proporciona detalles sobre:

  • Tu aplicación y caso de uso

  • Volumen de peticiones esperado

  • Implementación actual (con retroceso)

¿Te ha sido útil este artículo?