Inicio / Blog / Tareas programadas
Confiabilidad backend

El coste oculto de los cron jobs

Una expresión cron parece pequeña porque solo describe cuándo despertar un proceso. El coste de producción está alrededor del disparador: entregas duplicadas, ejecuciones solapadas, ventanas perdidas, zonas horarias, reintentos, escrituras parciales y la pregunta que aparece durante un incidente: ¿cómo sabemos que el trabajo terminó correctamente?

Programar es solicitar un intento de ejecución

El trabajo fiable necesita controles además del reloj
DisparadorAgenda y zona horaria.
AdquirirLease o clave lógica.
EjecutarLotes limitados y checkpoint.
RegistrarResultado y progreso.
RecuperarReintento, replay o escalado.

Los programadores difieren en entrega, retrasos y reintentos. Algunos pueden invocar dos veces; otros retrasan o pierden una ejecución bajo ciertas condiciones; el destino puede rechazar la llamada mucho después de la hora prevista. Trata la invocación como al menos una vez, salvo garantía contractual distinta, y haz idempotente el trabajo. Una clave de nombre de tarea y periodo lógico evita duplicar efectos de negocio.

Fallos que conviene diseñar

FalloSíntomaRespuesta de diseño
Invocación duplicadaDos facturas, exportaciones o avisos del mismo periodoClave idempotente, restricción única y upsert seguro
SolapamientoUna ejecución nueva compite por estado con la anteriorLease con vencimiento, concurrencia limitada o partición
Ejecución retrasada o perdidaInforme obsoleto o ventana de sincronización omitidaWatermark y consulta retroactiva del intervalo pendiente
Finalización parcialSe modifican algunos registros y el job fallaCheckpoint por lotes y replay seguro
Zona horaria o cambio estacionalLa tarea local se ejecuta a una hora inesperadaInstantes UTC y zona de negocio explícita
Fallo silenciosoSe invoca el scheduler pero la salida es incorrecta o vacíaValidar postcondiciones y alertar por falta de resultado

Separa el reloj de la intención de negocio

“Cada día a las 02:00” no basta si el negocio usa una zona local o cambia el horario estacional. Decide si el job sigue tiempo transcurrido UTC o calendario local. Persiste el periodo objetivo, no solo la hora de inicio. Una conciliación diaria debe saber qué fecha de negocio cubre aunque empiece tarde.

Limita y observa cada ejecución

Define duración máxima y tamaño de lote. Registra hora programada, inicio real, periodo lógico, intento, checkpoint, filas procesadas, resultado y tipo de error. Guarda el registro antes de efectos irreversibles. Alerta por finalización atrasada, no solo por excepciones: un job puede acabar con éxito y procesar cero registros por una ventana de consulta incorrecta.

Limita los reintentos y aplica backoff exponencial con jitter cuando corresponda, además de un destino terminal como DLQ o revisión operativa. No repitas a ciegas efectos no idempotentes. Define quién puede reprocesar un periodo y cómo se audita.

Cuándo cron debe convertirse en workflow

Una limpieza sencilla quizá solo necesite scheduler y handler idempotente. El trabajo con varias etapas, esperas, aprobación humana, compensaciones o progreso durable necesita un workflow o una máquina de estados respaldada por cola. Mantén el scheduler pequeño: calcula el periodo y encola; el worker lo reclama y procesa con concurrencia limitada.

Relacionado: colas para equipos pequeños, claves de idempotencia y observabilidad con presupuesto limitado.

En resumen

La sintaxis cron es lo más barato. Los jobs fiables necesitan identidad lógica, efectos idempotentes, control de solapamiento, recuperación de ventanas, reintentos acotados y evidencia de finalización. Diseña esas garantías y luego elige el scheduler.

Referencias