Hedged Requests
Nivel editorial: avanzado, según el Knowledge Map V0.3. Conviene comprender timeout, deadline, retry e idempotency antes de evaluar este patrón.
Qué es
Hedged Requests inicia una ejecución adicional equivalente cuando la primera tarda más de lo previsto, normalmente después de un retraso deliberado. La operación elige la primera respuesta que satisface su contrato y cancela o ignora las restantes. Es duplicación especulativa: el intento original todavía puede estar activo cuando empieza otro.
El objetivo es reducir tail latency, la cola de latencias elevadas que afecta a una fracción de solicitudes. Dean y Barroso explican cómo episodios de lentitud de componentes pueden dominar el tiempo de respuesta de servicios a gran escala. The Tail at Scale.
Hedging intercambia carga adicional por una posible reducción de tail latency. No añade capacidad, no garantiza que una segunda ejecución sea rápida y no vuelve segura una operación con efectos.
Diferencia con Retry
retry inicia otra tentativa después de un fallo o un resultado incierto que la política considera elegible. Hedging no necesita esperar ese resultado: basta con superar un umbral de demora mientras otra tentativa sigue pendiente.
Tiempo ->
A: inicia ---------------------------- responde
|
| umbral de demora
B: inicia -------- responde válida
|
resultado seleccionado
A: cancelación solicitada / respuesta posterior ignoradaUn Retry después de un Timeout también puede solaparse con trabajo remoto que no se detuvo. La diferencia es la decisión: en hedging se programa deliberadamente otra ejecución concurrente para competir por la respuesta, sin requerir que la espera del primer intento haya terminado.
La guía de gRPC presenta una política con retraso entre intentos, máximo de tentativas y un deadline compartido. También distingue errores no fatales de errores que terminan la operación. Es una implementación ilustrativa, no una dependencia del concepto ni una receta para todos los métodos.
Retraso y destinos
Una política delayed hedging da al primer intento una oportunidad de completar antes de duplicar trabajo. El umbral puede relacionarse con un percentil de la distribución observada para la operación, el destino y el contexto relevantes. Un p95 global que mezcla consultas muy distintas puede ser una referencia engañosa.
Si, en una distribución estable y representativa, el umbral coincide con p95 y se admite como máximo un hedge, aproximadamente el 5 % de solicitudes podría disparar una segunda tentativa. Esto es una estimación ilustrativa sobre cantidad de intentos, no sobre CPU adicional ni sobre una población futura. La distribución cambia bajo carga y los intentos duplicados pueden ser justamente los más caros.
Una réplica o endpoint distinto ofrece valor cuando evita parte de la causa de lentitud. Dos rutas que atraviesan la misma cola, base de datos o límite de cuota pueden estar fuertemente correlacionadas. Duplicar hacia el mismo cuello de botella aumenta competencia y puede empeorar ambas respuestas.
Elegir otro destino también debe preservar autenticación, parámetros y semántica de lectura. Una réplica más rápida pero incompatible con la frescura o consistencia requerida no aporta una respuesta válida.
Primera respuesta válida
El criterio es la primera respuesta exitosa que cumpla el contrato, no necesariamente el primer paquete ni cualquier respuesta HTTP. Un error rápido no se convierte en éxito por llegar antes. La política debe decidir qué errores invalidan toda la intención y cuáles permiten seguir esperando otra tentativa.
En lecturas replicadas, éxito incluye la versión o frescura mínima exigida. Si A responde con datos actuales y B con una copia obsoleta, elegir B solo por velocidad puede romper el significado de la consulta. Hedging no coordina por sí solo las réplicas ni determina consistencia.
Todos los intentos comparten deadline. El hedge consume el presupuesto que queda; no reinicia el límite total. Sus timeouts y cualquier espera local deben caber en ese margen. Empezar una nueva tentativa cuando ya no puede devolver un resultado útil añade costo sin cumplir el objetivo.
Ejemplo: consulta replicada
Una búsqueda tolera ejecución duplicada y respuestas con una versión mínima del índice. Tiene 300 ms de presupuesto total. Se inicia A; si a los 80 ms no produjo un resultado, se permite una tentativa B en otra réplica, siempre que haya capacidad y margen suficiente.
B responde válidamente a los 140 ms desde el inicio. Se entrega ese resultado y se solicita cancelar A. Si B responde con una versión no admitida, no gana; si vence el Deadline, la operación termina sin presentar como válida una respuesta tardía.
Estos valores son ilustrativos. Antes de adoptar la política hay que comparar la cola de latencia y la carga con y sin hedging, incluyendo lo que ocurre durante saturación. Una mejora de p99 en baja carga no demuestra una mejora del sistema durante un incidente.
Cancelación y consumo real
Cancelar o ignorar al perdedor evita que su resultado modifique la respuesta elegida, pero no garantiza detener instantáneamente el servidor. Puede haber consumido CPU, iniciado otra consulta o producido un efecto antes de recibir la señal.
gRPC Cancellation aclara que el handler debe cooperar para interrumpir su procesamiento; la biblioteca no detiene automáticamente todo código de aplicación. La propagación a servicios descendentes también necesita soporte.
El consumo incluye ejecuciones adicionales, conexiones, memoria y trabajo que continúa después de elegir ganador. Un límite mediante bulkhead debe contabilizar cada tentativa real, no solamente la intención del usuario. Si otros niveles agregan Retry o hedging propios, la amplificación puede multiplicarse.
Lecturas, escrituras e identidad
Lecturas replicadas, búsquedas y consultas tolerantes a duplicación suelen ser candidatas más apropiadas que operaciones con efectos. Aun una lectura puede generar auditoría, costo de proveedor o trabajo significativo; «read» no significa gratis ni ausencia absoluta de efectos auxiliares.
No presentar chargeCreditCard() como escritura generalmente segura para hedging. Dos intentos concurrentes pueden cobrar dos veces. Cancelar uno después de recibir la otra respuesta no revierte un cobro ni prueba que el perdedor no lo ejecutó.
Si una operación con efectos admite esta estrategia, necesita identidad común de intención, parámetros coherentes y garantías de idempotency o coordinación que cubran concurrencia y todos los destinos. La deduplicación independiente en cada réplica o proveedor puede ser insuficiente. Conviene distinguir la identidad de negocio compartida de los IDs individuales de tentativa usados para tracing.
Cuándo usarlo y límites
Evaluarlo cuando tail latency tenga impacto significativo, las ejecuciones duplicadas sean semánticamente seguras, existan destinos útiles y haya presupuesto de recursos. Limitar cantidad de intentos por operación y carga especulativa agregada; admitir un hedge es una decisión distinta de admitir el original.
Evitarlo cuando el sistema esté saturado, los efectos no estén protegidos, los destinos compartan el mismo cuello de botella o el costo adicional supere el beneficio. Fallas correlacionadas reducen la ganancia; una política fija puede disparar más duplicaciones justamente cuando la latencia sube por falta de capacidad.
Observar percentiles del resultado original y del compuesto, frecuencia de hedges, ganadores, errores, cancelaciones y trabajo residual. Medir solo la respuesta que ganó oculta el costo de los perdedores. resilience-patterns conecta esta optimización avanzada con las decisiones de tiempo, aislamiento y alternativas.