API y empresas

Polling de consultas sin saturar la API: Retry-After, ETag y espera con jitter

Consultar el estado cada segundo no hace que una búsqueda termine antes. Un contrato con Retry-After, ETag y una espera aleatoria reduce solicitudes repetidas, bytes y picos de clientes sincronizados.

Por Marco Ferreiro ·

Centro de operaciones tecnológicas con pulsos espaciados que representan un polling coordinado

Una consulta de infracciones puede depender de varias fuentes y tardar más que una solicitud HTTP convencional. El patrón habitual es aceptar el trabajo, devolver una URL de estado y permitir que el cliente pregunte hasta obtener un resultado terminal. El problema aparece cuando cientos de integraciones preguntan cada segundo aunque nada haya cambiado.

El polling puede ser predecible y eficiente si servidor y cliente comparten señales claras. Retry-After, ETag, solicitudes condicionales y jitter resuelven partes distintas del contrato.

Separar la creación del recurso de estado

La solicitud inicial crea o acepta una consulta y devuelve un identificador opaco. El estado vive en una URL estable, por ejemplo /consultas/{id}. El cliente no debería reenviar la búsqueda completa para preguntar cómo sigue: eso podría crear trabajos duplicados.

Una representación mínima puede incluir:

{
  "id": "qry_7f2...",
  "status": "running",
  "completedSources": 2,
  "totalSources": 5,
  "updatedAt": "2026-08-14T11:42:00Z"
}

El identificador no debe contener patente, CUIT ni otro dato legible. El estado tampoco debe afirmar “sin multas” mientras existan fuentes pendientes o fallidas.

Retry-After coordina la próxima consulta

RFC 9110 define Retry-After como un momento HTTP o una cantidad de segundos. En un recurso asincrónico sirve para orientar al cliente: antes de ese intervalo no hay motivo operativo para preguntar de nuevo.

No es una fecha de finalización. Si el proceso sigue activo al vencer, el servidor puede publicar otro Retry-After. Un cliente robusto también impone un mínimo local para evitar bucles ante un valor inválido y un máximo para no quedar dormido indefinidamente por una configuración errónea.

El intervalo puede cambiar según la etapa. Al principio quizá exista progreso frecuente; después, una fuente externa lenta justifica espaciar las consultas. Esa adaptación es preferible a prometer un tiempo universal.

ETag evita descargar el mismo estado

Cuando el servidor entrega la representación, puede asociarle un ETag. En la siguiente llamada el cliente envía If-None-Match con ese valor. Si la representación no cambió, HTTP permite responder 304 Not Modified sin repetir el cuerpo.

RFC 9110 define los validadores y RFC 9111 su uso en caché. Para este caso, el ETag debería cambiar cuando cambia cualquier dato público relevante: estado, avance, alcance, error o hora de actualización. No conviene derivarlo de datos sensibles ni exponer una huella reversible del contenido interno.

Un 304 no es un resultado de negocio. Sólo confirma que el cliente puede seguir usando la representación que ya posee. Si esa representación decía running, continúa diciendo running.

El jitter evita una estampida sincronizada

Si mil clientes reciben Retry-After: 30 a la misma hora y vuelven exactamente treinta segundos después, el servidor transforma una pausa útil en un nuevo pico. El jitter agrega una variación aleatoria después de la espera mínima.

Un esquema simple es:

próxima espera = retry_after + aleatorio(0, ventana_de_jitter)

La ventana puede ser una fracción del intervalo y debe tener un límite. No se resta jitter porque eso permitiría volver antes de lo indicado. La semilla y distribución no forman parte del contrato público; lo importante es que distintos clientes no queden alineados.

Si además hay fallos transitorios, la espera puede crecer por intento. El crecimiento y el jitter deben tener techo para que la recuperación sea observable y no se convierta en abandono silencioso.

429 no es lo mismo que estado pendiente

429 Too Many Requests, definido por RFC 6585, informa que el cliente excedió una política de solicitudes. No dice que la consulta de negocio falló. El cliente debe conservar el último estado conocido y reducir el ritmo.

El borrador activo del grupo HTTPAPI del IETF define campos RateLimit para comunicar políticas y disponibilidad de cuota. Al 14 de agosto de 2026 todavía es un Internet-Draft, no un RFC publicado. Sus señales son orientación sobre capacidad, no una garantía de que la próxima llamada será aceptada: puede existir otra protección por concurrencia, abuso o saturación.

Conviene separar tres señales:

Mezclarlas lleva a errores como marcar una consulta fallida por un límite temporal o reintentar agresivamente porque el trabajo todavía está pendiente.

Saber cuándo detenerse

El cliente deja de consultar ante estados terminales documentados, por ejemplo completed, partial o failed. partial necesita detalle por fuente para que el consumidor no lo convierta en “sin infracciones”. Un error permanente de autenticación, autorización o recurso inexistente tampoco debería entrar en un ciclo automático.

Además hacen falta límites locales: duración máxima de seguimiento, cantidad de fallos consecutivos y cancelación explícita. Alcanzar ese límite significa “seguimiento interrumpido”, no “consulta vacía”.

Los webhooks pueden reducir el polling, pero no eliminan la necesidad de reconciliar. Después de una notificación, el cliente obtiene el recurso final; si el aviso nunca llega, un polling lento puede recuperar el estado.

Un experimento reproducible antes de producción

El patrón puede probarse con un endpoint local y estados sintéticos. Prepará cien clientes simulados y una secuencia queued → running → completed. Compará tres estrategias durante el mismo período:

  1. intervalo fijo de un segundo;
  2. Retry-After sin jitter;
  3. Retry-After, jitter y If-None-Match.

Registrá cantidad de solicitudes, respuestas 200 y 304, bytes transferidos, concurrencia máxima y tiempo entre publicación y observación del estado terminal. No hace falta usar patentes reales ni conectarse a fuentes oficiales.

El resultado útil no es declarar un ganador universal. Es elegir parámetros que reduzcan carga sin aumentar de manera inaceptable el tiempo de detección para esa infraestructura. Después, esas métricas permiten ajustar el contrato con evidencia en vez de fijar un intervalo por intuición.

Un buen polling no consiste en preguntar más rápido. Consiste en que el servidor diga cuándo tiene sentido volver, el cliente evite descargar lo mismo y ambos distribuyan la recuperación en el tiempo.

Metodología

Alcance
Diseño de un endpoint de estado para consultas asincrónicas de infracciones, independiente de un proveedor o framework particular.
Unidad de análisis
Una solicitud condicional al recurso de estado y la transición observada entre dos consultas consecutivas.
Cobertura
Semántica derivada de los estándares HTTP sobre Retry-After, validadores, caché, 304, 429 y campos RateLimit.

Limitaciones

Fuentes

Preguntas frecuentes

¿Retry-After garantiza que la consulta estará terminada cuando venza la espera?

No. Indica cuánto conviene esperar antes de volver a solicitar el recurso, no una promesa de finalización. La respuesta siguiente puede mantener el estado pendiente y publicar un nuevo intervalo.

¿Un 304 Not Modified significa que la consulta terminó sin resultados?

No. Significa que la representación de estado no cambió respecto del ETag enviado por el cliente. El estado almacenado localmente puede seguir siendo pendiente, parcial, completo o fallido.

¿Por qué agregar jitter si todos respetan Retry-After?

Porque muchos clientes que reciben el mismo intervalo pueden volver exactamente al mismo tiempo. Una variación aleatoria controlada distribuye esas solicitudes sin ignorar la espera mínima indicada por el servidor.

¿El polling reemplaza a los webhooks?

No necesariamente. Puede ser el mecanismo principal o una vía de reconciliación cuando un webhook se demora o se pierde. Ambos deben compartir identificadores y estados coherentes.

Notas relacionadas