Hola chicos, tengo un flujo de trabajo de n8n que procesa registros de clientes y envía datos a una API externa. Cuando la API comienza a devolver 429 Too Many Requests, n8n reintentar las solicitudes, pero durante el tráfico intenso a veces termino con llamadas duplicadas a la API.
Mi flujo de trabajo actual es básicamente:
PostgreSQL → Loop Over Items → HTTP Request → Update PostgreSQL
Estoy considerando almacenar el estado de la solicitud de API en PostgreSQL: CREATE TABLE api_jobs (
id BIGSERIAL PRIMARY KEY,
customer_id BIGINT NOT NULL,
status TEXT NOT NULL DEFAULT ‘pending’,
attempts INT NOT NULL DEFAULT 0,
last_attempt_at TIMESTAMP,
external_id TEXT
);
Y antes de enviar la solicitud: UPDATE api_jobs
SET
status = ‘processing’,
attempts = attempts + 1,
last_attempt_at = NOW()
WHERE id = $1
AND status = ‘pending’
RETURNING *;
¿Recomendarías usar la configuración de reintentos de n8n, una cola de reintentos respaldada por PostgreSQL, backoff exponencial, o una combinación de estos?
¿Y cómo harías que las llamadas a la API sean idempotentes para que un reintento no cree accidentalmente el mismo cliente/pedido dos veces?
Describe el problema/error/pregunta
¿Cuál es el mensaje de error (si lo hay)?
Por favor, comparte tu flujo de trabajo
(Selecciona los nodos en tu lienzo y usa los atajos de teclado CMD+C/CTRL+C y CMD+V/CTRL+V para copiar y pegar el flujo de trabajo.)
Comparte el resultado devuelto por el último nodo
Información sobre tu configuración de n8n
Versión de n8n:
Base de datos (por defecto: SQLite):
Configuración EXECUTIONS_PROCESS de n8n (por defecto: own, main):
Ejecutando n8n a través de (Docker, npm, n8n cloud, aplicación de escritorio):
Hola @Kabrooks
Retry On Fail reintenta el nodo dentro de la misma ejecución, así que esos intentos terminan todos antes de que Update PostgreSQL se ejecute y attempts nunca se incrementa. La cola no tiene registro de que la solicitud se envió, es por eso que el mismo cliente recibe dos envíos. Ejecuta una capa de reintentos, no dos: desactiva Retry On Fail en el nodo HTTP Request y establece On Error en “Continue (using error output)”. El 429 llega entonces como un elemento en la rama de error, Update PostgreSQL registra el intento, y la siguiente ejecución programada hace el backoff.
La segunda fuente de duplicado es la consulta de reclamo. WHERE status = 'pending' deja una fila atascada en ‘processing’ para siempre si n8n se reinicia durante la solicitud, así que reclama por antigüedad en lugar de ampliar el filtro de estado:
WHERE id = $1
AND (
status = 'pending'
OR (status = 'processing' AND last_attempt_at < NOW() - INTERVAL '5 minutes')
)