Módulo 6: Manejo de Errores

Retry Strategies Profundizadas

Descripción de la cápsula

En G1-M06-06 viste retry on fail básico. Esta cápsula profundiza las estrategias: cuándo retry simple, cuándo exponential backoff, cuándo retry con jitter, y cómo configurarlas en n8n.


Lo que vas a aprender

  • 3 estrategias de retry: fijo, exponential, con jitter
  • Configurar retry on fail según estrategia
  • Cuándo cada una es apropiada
  • Reconocer anti-patterns comunes de retry

Estrategia 1: Retry fijo

Intento 1: wait 1s
Intento 2: wait 1s
Intento 3: wait 1s

Configuración en n8n Retry On Fail:

  • Max Tries: 3
  • Wait Between Tries: 1000ms

Cuándo usar

  • Errores transitorios cortos
  • API que se recupera rápido
  • Cuando tiempos predecibles

Cuándo NO

  • API saturada que necesita tiempo para recuperar (backoff es mejor)
  • Rate limits (debes esperar más entre cada intento)

Estrategia 2: Exponential backoff

Intento 1: wait 1s
Intento 2: wait 2s
Intento 3: wait 4s
Intento 4: wait 8s

Cada retry duplica el wait. Filosofía: si está fallando, darle más tiempo de recuperarse.

En n8n

n8n's Retry On Fail nativo no soporta exponential directamente en algunas versiones. Workarounds:

Workaround 1: Múltiples nodos con Wait creciente

[HTTP] → fail → [Wait 1s] → [HTTP retry] → fail → [Wait 2s] → [HTTP retry] → ...

Verboso pero funcional.

Workaround 2: Code node con loop manual

let retries = 0;
const maxRetries = 5;
let result;

while (retries < maxRetries) {
  try {
    result = await fetch(url);
    if (result.ok) break;
  } catch (e) {
    const wait = Math.pow(2, retries) * 1000;
    await new Promise(r => setTimeout(r, wait));
    retries++;
  }
}

Workaround 3: SplitInBatches con Set incremental

[Set: retry_count = 0, wait_time = 1000]
   │
[SplitInBatches batch=1]
   │
[HTTP]
   │
[IF: success?]
├─ TRUE → fin
└─ FALSE → [Set: wait_time = wait_time * 2] → [Wait dynamic] → loop back

Estrategia 3: Exponential con jitter

Igual que exponential pero con randomness:

Intento 1: wait 1s ± random(0-0.5s) = 0.5-1.5s
Intento 2: wait 2s ± random(0-1s)    = 1-3s
Intento 3: wait 4s ± random(0-2s)    = 2-6s

Por qué jitter

Si 1000 clientes tienen retry exponential sincronizado sin jitter, todos reintentan al mismo tiempo:

  • Intento 1 fallido a las 12:00:00 → todos retry a 12:00:01
  • API recibe 1000 requests simultáneas → falla otra vez
  • Loop interminable

Con jitter, los retries se distribuyen en una ventana → la carga es manejable.

Implementación en Code node

const baseWait = Math.pow(2, retries) * 1000;
const jitter = Math.random() * baseWait * 0.5;
const totalWait = baseWait + jitter;

Decisión: qué estrategia

CasoEstrategia
API muy estable, errores rarosRetry fijo simple
API que se sobrecargaExponential backoff
Múltiples clientes/instancesExponential con jitter
Rate limits del APIWait Retry-After específico (no retry pattern)

Max retries: ¿cuántos?

Demasiado pocos (1-2)

Errores transitorios de medio plazo no se recuperan en 2 retries.

Demasiado muchos (10+)

  • Workflow tarda mucho en fallar definitivamente
  • Si el error es no-transitorio, son retries inútiles
  • Consume recursos sin beneficio

Rango razonable

3-5 retries cubre la mayoría de transients sin desperdiciar recursos.

Para casos especiales:

  • APIs muy críticas con SLA estricto: 5-7
  • Operaciones idempotentes seguras: hasta 10
  • Operaciones que tienen costo monetario por intento: 1-2

Retry con condición

A veces quieres retry solo si la condición lo amerita, no en todos los errores.

Patrón

[HTTP con Continue on Fail]
   │
[IF: error es transient?]
├─ TRUE → [Wait + retry HTTP] (loop hasta max)
└─ FALSE → [skip + log] o [alert]

Categoriza el error (cápsula 02) antes de decidir retry.


Anti-patrones del retry

Anti-pattern 1: Retry sin max

Loop infinito. Workflow nunca termina.

Fix: siempre max retries.

Anti-pattern 2: Wait muy corto en exponential

Intento 1: wait 100ms
Intento 2: wait 200ms
Intento 3: wait 400ms

Demasiado rápido. La API no tiene tiempo de recuperarse.

Fix: empezar con 1s mínimo.

Anti-pattern 3: Retry para errores 4xx

400/404 no se arreglan con retry. Es bug.

Fix: clasificar antes de retry.

Anti-pattern 4: Retry sin logging

Workflow reintenta 5 veces sin loggear. Después falla. No sabes por qué.

Fix: log cada intento con razón del fallo.

Anti-pattern 5: Retry crítico sin alert

Workflow falla todos los días por 30 días. Nadie revisa. Cliente pregunta por qué no funciona.

Fix: alert cuando max retries se alcanza.


Cap en exponential

Sin cap, después de 10 retries esperas 1024 segundos (~17 min).

Implementación

const wait = Math.min(Math.pow(2, retries) * 1000, 60000); // cap 60s

Ejemplo: workflow con retry inteligente

[Trigger]
   │
[HTTP con Continue on Fail]
   │
[Set: clasificar error]
   │
[Switch: error_category]
├─→ "success" → continuar
├─→ "transient" → [Retry hasta 3, exponential] → continuar o alert si falla
├─→ "rate_limit" → [Wait Retry-After + retry 1] → continuar o alert
├─→ "auth" → [Alert inmediato] → terminar
└─→ "client_error" → [Log + skip] → continuar

Cada categoría su estrategia.


Resumen

  • 3 estrategias: fijo, exponential, exponential con jitter
  • Jitter importante en sistemas distribuidos
  • Max retries 3-5 razonable para mayoría
  • Cap el wait para no esperas excesivas
  • Categorizar antes de retry
  • 5 anti-patterns: sin max, wait muy corto, retry para 4xx, sin logging, sin alert

Lo que sigue: Continue on Fail patterns — manejar fallos sin parar el flow.


Creado: Mayo 11, 2026 Versión: 1.0