Tareas programadas o disparadas por eventos: cuándo usar cada una
Una automatización arranca por un reloj o por algo que pasó. Esta guía da criterios concretos para elegir el disparador y muestra cómo combinar los dos sin duplicar trabajo.

Las dos formas de arrancar
Programada. Corre a una hora fija o cada cierto intervalo. Ejemplo: todos los días a las 6:00 revisa facturas vencidas.
Disparada por eventos. Corre cuando ocurre algo. Ejemplo: la pasarela avisa por webhook que un pago falló.
Las dos sirven. La pregunta es qué necesita el proceso.
Cinco criterios para decidir
| Criterio | Programada | Por eventos |
|---|---|---|
| Latencia necesaria | Minutos u horas sirven | Segundos importan |
| Fuente | No emite eventos | Emite webhooks o mensajes |
| Volumen | Lotes grandes, procesamiento agrupado | Casos individuales |
| Fiabilidad de la fuente | Funciona aunque se pierdan avisos | Depende de que los eventos lleguen |
| Costo | Predecible | Proporcional a la actividad |
Regla práctica: si una persona notaría la demora, usa eventos. Si no, empieza por una tarea programada, que es más fácil de operar.
Ejemplos
Programadas:
- Reporte diario de cartera.
- Escalera de recordatorios de cobro.
- Conciliación bancaria con el extracto del día.
- Limpieza de datos vencidos según la política de retención.
Por eventos:
- Pago fallido: avisar al cliente y reintentar.
- Mensaje entrante de WhatsApp.
- Factura recibida en el buzón de proveedores.
- Cambio de datos bancarios de un proveedor: alerta inmediata.
El patrón que recomendamos: eventos más barrido
Los eventos se pierden. Un webhook falla, un servicio está caído o un mensaje llega duplicado. Por eso los flujos importantes por eventos llevan una tarea programada de respaldo.
El barrido consulta la fuente y encola lo que no se procesó. El worker es idempotente, así que procesar dos veces el mismo caso no hace daño.
Cómo hacer robusta una tarea programada
- Evita ejecuciones superpuestas. Si la tarea de las 6:00 sigue corriendo a las 7:00, la de las 7:00 no debe arrancar. Usa un bloqueo.
- Procesa por ventanas con marca de agua. Guarda hasta qué registro procesaste. La siguiente ejecución sigue desde ahí.
- Reanuda tras fallos. Si la tarea cae a mitad, al volver no repite lo hecho.
- Alerta si no corrió. Una tarea que deja de correr no genera errores. Monitorea que haya terminado en su horario.
with lock("cobranza-diaria", timeout=3600):
desde = estado.get("marca")
for factura in erp.vencidas(desde=desde):
procesar(factura) # idempotente
estado.set("marca", factura.actualizada_en)
heartbeat("cobranza-diaria")Cómo hacer robusto un flujo por eventos
- Responde rápido al webhook. Valida, guarda y encola. Procesa después.
- Verifica la firma del emisor.
- Deduplica por id de evento.
- Ordena cuando importa. Los eventos pueden llegar desordenados. Usa la versión o la fecha del recurso y descarta los viejos.
- Cola de mensajes fallidos. Lo que falla varias veces va a una cola para revisión.
Dónde entra el agente de IA
El disparador decide cuándo. El agente decide cómo responder dentro del caso. Mantén esa separación:
- El disparador y la cola son código simple y confiable.
- El agente recibe un caso con sus datos y devuelve una acción propuesta.
- Las acciones de riesgo pasan por la política de aprobaciones.
Un error frecuente es pedirle al agente que "revise cada cierto tiempo si hay algo". Eso es una tarea programada. Escríbela como tal y llama al agente solo con los casos que encontró.
Una prueba rápida para elegir
Responde tres preguntas sobre el proceso:
- ¿Qué pasa si la acción ocurre una hora tarde? Si nada grave, empieza con una tarea programada.
- ¿La fuente envía eventos confiables y firmados? Si no, la tarea programada es tu única opción segura.
- ¿El volumen llega en picos? Si sí, los eventos necesitan cola y límite de concurrencia desde el primer día.
Anota las respuestas en la documentación del flujo. Cuando alguien proponga cambiar el disparador, ya tiene el criterio original.
Costo
Las tareas programadas que llaman a un modelo sobre todos los registros, cambien o no, gastan de más. Procesa solo lo nuevo o lo modificado desde la marca de agua.
En flujos por eventos, controla picos. Un lote masivo de eventos puede disparar miles de llamadas al modelo. Pon un límite de concurrencia en el worker.
Métricas
| Métrica | Para qué |
|---|---|
| Latencia de evento a acción | Verificar que el flujo por eventos cumple su propósito |
| Casos recuperados por el barrido | Medir cuántos eventos se pierden |
| Ejecuciones programadas fallidas o ausentes | Detectar tareas que dejaron de correr |
| Duración de cada ejecución | Anticipar superposiciones |
| Eventos en cola de fallidos | Revisar errores persistentes |
Si el barrido recupera muchos casos, el problema está en la recepción de eventos.
Errores comunes
- Eventos sin barrido de respaldo.
- Tareas programadas sin bloqueo.
- Procesar en el handler del webhook.
- Llamar al modelo sobre registros sin cambios.
- No monitorear que la tarea corrió.
Checklist
Preguntas frecuentes
¿Puedo empezar con tareas programadas y migrar después?
Sí. Si el worker ya es idempotente y recibe casos individuales, cambiar el disparador es un ajuste acotado.
¿Cada cuánto debe correr el barrido?
Según cuánto tolere el proceso una demora. Para pagos fallidos, minutos u horas. Para reportes, una vez al día.
¿Qué pasa si la fuente no emite eventos?
Usa una tarea programada que consulte cambios. Si la fuente permite filtrar por fecha de modificación, la consulta es barata.