Saltar al contenido principal
Principiante IACódigoTutorial

Error 429 Too Many Requests en APIs de IA: Causas y Solución

¿Error 429 al llamar a la API de OpenAI, Anthropic o Google? Causas técnicas, código para solucionarlo con retry y backoff exponencial, y límites por proveedor.

Fran Cobos 9 min de lectura 1778 palabras

Tabla de contenidos

Estás desarrollando tu app, los tests pasan, todo funciona… y de repente:

Error 429: Too Many Requests
Rate limit reached for gpt-4.1 in organization org-xxx on tokens per min (TPM):
Limit 30000, Used 28500, Requested 2000.

Tu app se para. Tus usuarios ven errores. Y tú no sabes si es un bug, si has gastado demasiado o si te están bloqueando.

Es el Error 429. El error más común (y más frustrante) al trabajar con APIs de IA. En este artículo te explico por qué ocurre y te doy código listo para solucionarlo.

¿Qué significa el Error 429 Too Many Requests?

El código HTTP 429 significa que el servidor rechaza tu petición porque has superado un límite de uso (rate limit). No es un bug de tu código ni un problema del servidor — es un mecanismo de protección.

En las APIs de IA, los límites existen por:

  • Proteger la infraestructura — los modelos de IA consumen GPU caras
  • Garantizar servicio equitativo — que un usuario no acapare todos los recursos
  • Controlar costes — evitar facturas sorpresa por bucles infinitos

¿Por qué ocurre? Las 4 causas técnicas

1. Rate limit por peticiones (RPM)

Has hecho demasiadas peticiones en un minuto. Cada proveedor tiene un límite de Requests Per Minute (RPM).

// ❌ Esto dispara el 429: 100 peticiones simultáneas
const promises = urls.map(url => openai.chat.completions.create({...}));
await Promise.all(promises); // 💥 429

2. Rate limit por tokens (TPM)

Has enviado demasiados tokens en un minuto. Aunque hagas pocas peticiones, si cada una lleva un contexto de 50K tokens, puedes superar el límite de Tokens Per Minute (TPM).

// ❌ Enviar un archivo enorme como contexto
const context = fs.readFileSync('codebase-entero.txt', 'utf-8'); // 100K tokens
await openai.chat.completions.create({
  messages: [{ role: 'user', content: context + '\nResume esto' }],
}); // 💥 429 por TPM

3. Cuota mensual agotada

Has gastado el presupuesto que tu cuenta permite. OpenAI y Anthropic tienen límites de gasto mensual por tier. Si estás en Tier 1 y tu límite es $100/mes, al llegar a esa cifra obtienes un 429 hasta el siguiente ciclo.

4. Peticiones concurrentes excesivas

Algunos proveedores limitan cuántas peticiones pueden estar procesándose a la vez. Si lanzas 50 llamadas simultáneas y el límite es 25, las que sobren reciben un 429.

Solución paso a paso

Paso 1: Identifica qué límite estás superando

El Error 429 viene con headers que te dicen qué está pasando:

try {
  const response = await openai.chat.completions.create({...});
} catch (error) {
  if (error.status === 429) {
    console.log('Tipo:', error.headers['x-ratelimit-limit-requests']);
    console.log('Restantes:', error.headers['x-ratelimit-remaining-requests']);
    console.log('Reset en:', error.headers['x-ratelimit-reset-requests']);
    console.log('Retry-After:', error.headers['retry-after']);
  }
}
HeaderQué indica
x-ratelimit-limit-requestsTu límite de RPM
x-ratelimit-remaining-requestsPeticiones que te quedan
x-ratelimit-limit-tokensTu límite de TPM
x-ratelimit-remaining-tokensTokens que te quedan
retry-afterSegundos que debes esperar

Paso 2: Implementa retry con backoff exponencial

La solución estándar: si recibes un 429, espera y reintenta. Cada reintento duplica el tiempo de espera para no saturar el servidor.

async function callWithRetry(fn, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status !== 429 || attempt === maxRetries - 1) {
        throw error;
      }

      // Backoff exponencial: 1s, 2s, 4s, 8s, 16s
      const retryAfter = error.headers?.['retry-after'];
      const delay = retryAfter
        ? parseInt(retryAfter) * 1000
        : Math.pow(2, attempt) * 1000 + Math.random() * 1000;

      console.log(`429 recibido. Reintentando en ${Math.round(delay / 1000)}s...`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Uso
const response = await callWithRetry(() =>
  openai.chat.completions.create({
    model: 'gpt-4.1',
    messages: [{ role: 'user', content: 'Hola' }],
  })
);

El + Math.random() * 1000 (jitter) es importante: evita que múltiples instancias de tu app reintenten al mismo tiempo y vuelvan a saturar el límite.

Paso 3: Controla el flujo de peticiones (rate limiter)

Si haces muchas llamadas (scraping, procesamiento masivo, agentes), necesitas un rate limiter que controle cuántas peticiones se envían por minuto.

class RateLimiter {
  constructor(maxPerMinute) {
    this.maxPerMinute = maxPerMinute;
    this.queue = [];
    this.timestamps = [];
  }

  async acquire() {
    const now = Date.now();
    this.timestamps = this.timestamps.filter(t => now - t < 60000);

    if (this.timestamps.length >= this.maxPerMinute) {
      const waitTime = 60000 - (now - this.timestamps[0]);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }

    this.timestamps.push(Date.now());
  }
}

// Uso: máximo 50 peticiones/minuto
const limiter = new RateLimiter(50);

async function callAPI(prompt) {
  await limiter.acquire();
  return openai.chat.completions.create({
    model: 'gpt-4.1-mini',
    messages: [{ role: 'user', content: prompt }],
  });
}

// Procesar 500 items sin 429
for (const item of items) {
  const result = await callAPI(item.text);
  // ...
}

Paso 4: Optimiza tokens para gastar menos cuota

Menos tokens = menos probabilidad de alcanzar el TPM.

// ❌ System prompt de 500 tokens
system: "Eres un asistente altamente cualificado experto en... [párrafo enorme]"

// ✅ System prompt de 30 tokens
system: "Senior dev. Responde en español. Solo código, sin explicación."

// ❌ Enviar todo el archivo
content: entireFileContent // 50K tokens

// ✅ Enviar solo lo relevante
content: extractRelevantChunk(entireFileContent, query) // 2K tokens

Paso 5: Cachea respuestas repetidas

Si haces la misma pregunta varias veces, no llames a la API de nuevo.

const cache = new Map();

async function cachedCompletion(prompt, model = 'gpt-4.1-mini') {
  const key = `${model}:${prompt}`;

  if (cache.has(key)) {
    return cache.get(key);
  }

  const response = await callWithRetry(() =>
    openai.chat.completions.create({
      model,
      messages: [{ role: 'user', content: prompt }],
    })
  );

  const result = response.choices[0].message.content;
  cache.set(key, result);
  return result;
}

Para producción, sustituye el Map() por Redis o un archivo JSON persistente.

Límites reales por proveedor en 2026

Estos son los límites con los que te vas a encontrar:

OpenAI

TierRPM (GPT-4.1)TPM (GPT-4.1)Gasto mensual máx.
Free340.000
Tier 1 ($5+ gastados)500200.000$100
Tier 2 ($50+)5.0002.000.000$500
Tier 3 ($100+)5.0004.000.000$1.000
Tier 5 ($1.000+)10.00030.000.000$5.000

Anthropic (Claude)

TierRPMTPM inputTPM output
Free (Build)520.0008.000
Tier 1 ($5+)5080.00016.000
Tier 2 ($40+)1.000160.00032.000
Tier 3 ($200+)2.000320.00064.000
Tier 4 ($400+)4.000640.000128.000

Google (Gemini)

PlanRPMTPMPrecio
AI Studio (gratis)151.000.000$0
AI Studio (pay-as-you-go)2.0004.000.000Variable
Vertex AI1.000+ConfigurableVariable

DeepSeek

PlanRPMTPM
API estándar60500.000
Con saldo > $103002.000.000

Cuándo la solución es cambiar de proveedor

A veces el 429 te está diciendo que necesitas otro approach:

SituaciónSolución
Necesitas >2.000 RPM y estás en Tier 1 de OpenAIGasta más para subir a Tier 2+, o usa Google AI Studio (2.000 RPM pay-as-you-go)
Procesas datos masivos (10K+ documentos)Usa Batch API de OpenAI (50% descuento + sin rate limit con cola)
Tu app tiene picos impredeciblesDistribuye entre proveedores: OpenAI + Anthropic + Google
No puedes permitirte rate limitsEjecuta modelos locales con Ollama (sin límites)
Haces muchas peticiones idénticasPrompt Caching (90% descuento en tokens cacheados)

Si estás evaluando costes, consulta la calculadora de precios de IA para comparar todos los proveedores. Y si buscas opciones sin coste, mira cómo usar la API de ChatGPT y Claude gratis. Si el error ocurre en tu extensión de VS Code, consulta los 5 errores comunes con Copilot, Cline y Cursor.

Este error también está documentado en el índice de errores comunes en desarrollo, donde encontrarás guías para otros errores frecuentes como CORS y ENOENT.

Solución completa: wrapper robusto para producción

Aquí tienes una clase que combina retry, rate limiting y cache. Lista para copiar en tu proyecto:

import OpenAI from 'openai';

class RobustAIClient {
  constructor({ apiKey, maxRPM = 50, maxRetries = 5 }) {
    this.client = new OpenAI({ apiKey });
    this.maxRetries = maxRetries;
    this.timestamps = [];
    this.maxRPM = maxRPM;
    this.cache = new Map();
  }

  async rateLimit() {
    const now = Date.now();
    this.timestamps = this.timestamps.filter(t => now - t < 60000);
    if (this.timestamps.length >= this.maxRPM) {
      const wait = 60000 - (now - this.timestamps[0]);
      await new Promise(r => setTimeout(r, wait));
    }
    this.timestamps.push(Date.now());
  }

  async chat(prompt, { model = 'gpt-4.1-mini', useCache = true } = {}) {
    const cacheKey = `${model}:${prompt}`;
    if (useCache && this.cache.has(cacheKey)) return this.cache.get(cacheKey);

    await this.rateLimit();

    for (let attempt = 0; attempt < this.maxRetries; attempt++) {
      try {
        const res = await this.client.chat.completions.create({
          model,
          messages: [{ role: 'user', content: prompt }],
        });
        const result = res.choices[0].message.content;
        if (useCache) this.cache.set(cacheKey, result);
        return result;
      } catch (err) {
        if (err.status !== 429 || attempt === this.maxRetries - 1) throw err;
        const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
        console.warn(`429 → retry ${attempt + 1}/${this.maxRetries} en ${Math.round(delay / 1000)}s`);
        await new Promise(r => setTimeout(r, delay));
      }
    }
  }
}

// Uso
const ai = new RobustAIClient({
  apiKey: process.env.OPENAI_API_KEY,
  maxRPM: 100,
});

const answer = await ai.chat('Explica qué es un rate limiter');

Si estás construyendo agentes que hacen múltiples llamadas, este wrapper te evitará el 429 en el 99% de los casos. Para un ejemplo real de agente en producción, sigue mi tutorial de agente con LangChain y Node.js.

Checklist rápido anti-429

  • ¿Tienes retry con backoff exponencial + jitter?
  • ¿Controlas el RPM con un rate limiter?
  • ¿Cacheas respuestas repetidas?
  • ¿Usas el modelo más pequeño posible para cada tarea?
  • ¿Limitas max_tokens en cada petición?
  • ¿Envías solo el contexto necesario (no archivos enteros)?
  • ¿Sabes en qué tier estás y cuáles son tus límites?
  • ¿Tienes un fallback a otro proveedor si el principal falla?

Si marca todos: el Error 429 no debería volver a pararte.


¿Te ha funcionado? Si conoces otro truco para manejar rate limits o has encontrado un caso raro de 429, compártelo en LinkedIn o visita mi portfolio para ver proyectos donde gestiono miles de llamadas a APIs de IA en producción.

Fran Cobos

Fran Cobos

Desarrollador Full Stack especializado en IA aplicada, automatización y desarrollo web. Escribo sobre herramientas, tutoriales y casos reales para programadores.

¿Necesitas desarrollo a medida?

Apps web, IA, módulos ERP — cuéntame tu proyecto.