Backoff
Qué es
Backoff es una política de espera entre intentos que controla el ritmo al volver a ejecutar trabajo. Define cuánto retrasar el próximo intento en función de la secuencia, del estado anterior o de señales de la dependencia.
Su responsabilidad es temporal. retry decide si repetir es apropiado; jitter introduce variación para que muchos clientes no coincidan. Backoff no hace seguro un efecto no idempotente ni garantiza que una dependencia se recupere.
Qué problema resuelve
Si un broker deja de aceptar publicaciones, miles de callers pueden repetir inmediatamente. Esas llamadas consumen CPU, conexiones y capacidad de rechazar solicitudes mientras el servicio intenta recuperarse.
Espaciar intentos reduce la frecuencia de cada secuencia y da tiempo a que cambie la causa del fallo. También introduce espera: una dependencia que se recupera justo después de un intento podría permanecer sin recibir otra llamada hasta que termine la pausa.
El balance depende de la duración esperada del fallo, la utilidad del trabajo y el presupuesto total. No hay un calendario que sea óptimo para todas las operaciones.
Estrategias básicas
Sea n el número de espera después del primer intento fallido. Los valores siguientes son ejemplos de políticas, no recomendaciones universales:
| Estrategia | Esperas ilustrativas | Característica |
|---|---|---|
| Constant | 1 s, 1 s, 1 s, 1 s | Ritmo fijo; no aumenta la pausa ante persistencia del fallo. |
| Linear | 1 s, 2 s, 3 s, 4 s | Añade un incremento fijo en cada espera. |
| Exponential | 1 s, 2 s, 4 s, 8 s | Multiplica la espera; puede crecer muy rápidamente. |
| Bounded exponential | 1 s, 2 s, 4 s, 8 s, 16 s, 16 s | Crece hasta un cap y luego conserva ese máximo base. |
1s -> 2s -> 4s -> 8s -> 16s -> capLa primera espera, el factor y el cap son decisiones independientes. Un cap de tiempo no es un límite de intentos ni un presupuesto agregado de carga. Que todas las esperas sean finitas no implica que el proceso deje de reintentar.
Los clientes oficiales también combinan estas políticas con límites y clasificación de errores. gRPC, por ejemplo, documenta retraso inicial, máximo y multiplicador como parte de su política de retry. El concepto no depende de ese framework. gRPC: Retry configuration.
Backoff y sincronización
Si todos los clientes fallan juntos y usan el mismo calendario determinista, vuelven a llamar juntos a uno, tres y siete segundos después del fallo inicial. Sus pausas crecen, pero los picos permanecen alineados.
En el cap también pueden seguir enviando oleadas periódicas. Marc Brooker muestra esta diferencia entre espaciar llamadas y distribuirlas: exponential backoff por sí solo conserva clusters de intentos en su experimento. Exponential Backoff And Jitter.
jitter varía la espera dentro de una política definida para reducir coincidencias. Esa modificación puede cambiar el promedio de espera, por lo que no conviene sustituir una estrategia por otra suponiendo igual tasa de intentos.
Ejemplo: relay de outbox
Un relay intenta publicar evt-42-created y el broker devuelve un fallo elegible. La política conserva el registro y su identidad, y programa una nueva tentativa con pausa creciente hasta un cap.
El worker no debería ocupar una conexión de base de datos o mantener un lock de la transacción de negocio durante toda la pausa. En transactional-outbox, el cambio local ya terminó; la programación y los claims del relay necesitan su propia recuperación.
Si el proceso reinicia y todas las instancias vuelven siempre a la pausa inicial mínima, puede reaparecer una ráfaga. Conservar o reconstruir el progreso apropiado, junto con jitter y límites de concurrencia, permite que reiniciar no borre todas las precauciones.
Otro mensaje independiente no tiene necesariamente que heredar la espera de este registro. El ámbito de backoff debe elegirse: por intento, intención, conexión o dependencia. Un broker completamente caído puede justificar control más amplio; un único mensaje inválido no debería detener indiscriminadamente todos los demás.
Deadline y señales del servidor
La pausa consume presupuesto igual que la llamada. Antes de esperar hay que verificar si quedará tiempo útil para el próximo intento, respetando cancelación y deadline. Una espera que no cabe puede terminar la secuencia actual; no se debe iniciar otro intento con un presupuesto inventado.
Algunos protocolos comunican cuándo volver a intentar. La política necesita interpretar esa señal conforme al contrato, sin acortarla arbitrariamente. HTTP Retry-After puede indicar una fecha o un intervalo de espera; si no cabe en el presupuesto disponible, el caller puede tener que abandonar esa tentativa de recuperación. RFC 9110, sección 10.2.3.
Una señal de espera no asegura que la dependencia estará sana al terminar ni autoriza cualquier número de llamadas. Sigue haciendo falta clasificación, seguridad del efecto y presupuesto de carga.
Failure scenarios y trade-offs
- Sin cap: las esperas pueden superar la vigencia del trabajo o dificultar descubrir recuperación.
- Cap sin límite de intentos: muchos clientes mantienen una carga sostenida aunque cada uno espere.
- Calendario idéntico: los clientes producen picos conjuntos, incluso con crecimiento exponencial.
- Bloqueo durante la pausa: threads, conexiones o locks permanecen ocupados sin producir progreso.
- Reinicios que resetean todo: varios procesos pueden regresar simultáneamente al ritmo más agresivo.
- Errores permanentes: hacerlos más lentos no los vuelve transitorios.
Usar backoff para espaciar trabajo elegible cuando la espera puede aumentar la probabilidad de éxito o reducir presión. No usarlo como sustituto de capacidad, límites agregados, circuit-breaker o idempotency. Puede elevar latencia y backlog, y necesita observabilidad del tiempo entre intentos y de las intenciones pendientes.
Relaciones
retry conserva la decisión y los límites de repetir; jitter distribuye el calendario; timeout limita cada espera de una llamada. resilience-patterns conecta esas decisiones sin presentar exponential backoff como una receta suficiente para toda recuperación.