Programación de tareas en Linux: comparación entre cron y systemd timer

En la administración de sistemas Linux, saber cuándo se ejecuta una tarea es tan importante como saber qué se ejecuta. El viejo amigo es cron, mientras que en las distribuciones modernas se usa cada vez más systemd timer.


1. ¿Por qué comparar cron y systemd timer?



La mayoría de los servidores Linux tienen requisitos similares:

  • Ejecutar una copia de seguridad a las 3 a.m. todos los días
  • Ejecutar un script de comprobación de salud cada 5 minutos
  • Comprimir y limpiar logs cada domingo
  • Ejecutar una tarea de inicialización una sola vez, un minuto después del arranque

Tradicionalmente todo se hacía con cron, pero con la adopción de systemd como init, el timer unit se ha convertido en una alternativa poderosa.


2. Conceptos básicos de cron

2.1 ¿Qué es cron?

cron es un programador antiguo de Unix/Linux que ejecuta comandos según un horario predefinido, gestionado principalmente a través de archivos crontab.

2.2 Ubicación de la configuración

  • Sistema completo: /etc/crontab, /etc/cron.d/
  • Por usuario: crontab -e (crontab por usuario)

Ejemplo: ejecutar un script de copia de seguridad cada día a las 3 a.m.:

0 3 * * * /usr/local/bin/backup.sh

Los campos significan:

Min  Hour  Day  Month  Weekday  Command
0    3     *    *      *        /usr/local/bin/backup.sh

2.3 Ventajas de cron

  • Herramienta probada y confiable
  • Concepto idéntico en la mayoría de sistemas Unix/Linux
  • Sintaxis sencilla y abundantes ejemplos
  • Disponible incluso en sistemas sin systemd

2.4 Limitaciones de cron

  • Separado de los servicios, dificultando el rastreo de qué tarea pertenece a qué servicio
  • Verificación de estado y logs dispersos (syslog, correo, etc.)
  • Gestión de dependencias débil (no se garantiza que otro servicio esté activo primero)
  • Programación basada en tiempo relativo (ej. “5 minutos después del arranque”) es complicada

3. Conceptos básicos de systemd timer



3.1 ¿Qué es un systemd timer?

Un timer unit de systemd dispara otro service unit bajo ciertas condiciones (hora, tiempo transcurrido después del arranque, etc.).

La estructura siempre es un par:

  • myjob.service → define la tarea real
  • myjob.timer → define cuándo se ejecuta

3.2 Ejemplo básico de servicio + timer

Ejecutar una copia de seguridad diaria a las 3 a.m. con systemd timer:

(1) Servicio: /etc/systemd/system/backup.service

[Unit]
Description=Daily backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

(2) Timer: /etc/systemd/system/backup.timer

[Unit]
Description=Run daily backup at 3:00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

Activación:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer

3.3 Ventajas de systemd timer

  • Relación clara con el servicio: se ve qué servicio está ligado a qué timer
  • Gestión de logs sencilla: journalctl -u backup.service
  • Condiciones de activación flexibles:
  • OnCalendar= (similar a cron)
  • OnBootSec= (X segundos después del arranque)
  • OnUnitActiveSec= / OnUnitInactiveSec= (X tiempo después de la última ejecución)
  • Manejo de dependencias: After=network-online.target, Requires=...
  • Integrado con el ecosistema systemd: systemctl list-timers, systemctl status

3.4 Desventajas de systemd timer

  • Curva de aprendizaje mayor que cron (dos archivos por tarea)
  • Depende de systemd (no funciona en sistemas muy antiguos o no basados en systemd)
  • Para tareas de una sola línea puede parecer excesivo

4. Comparación funcional

Característica cron systemd timer
Ubicación /etc/crontab, crontab -e /etc/systemd/system/*.service/*.timer
Objetivo Cualquier comando/ script Servicio de systemd
Expresión de tiempo Expresión cron (5 campos) OnCalendar, OnBootSec, etc.
Tiempo relativo (X minutos después del arranque) Limitado, requiere trucos OnBootSec, OnStartupSec directamente
Gestión de fallos/reintentos Necesita implementación externa Configurable en la unidad de servicio
Logs syslog, correo, etc. journalctl -u <service>
Dependencias (red, FS) No soportado After=, Requires=
Integración con el sistema Baja Alta (con systemd)
Portabilidad Alta Depende de systemd

5. Ejemplos prácticos

5.1 Copia de seguridad diaria a las 3 a.m.: cron vs timer

Versión cron

0 3 * * * /usr/local/bin/backup.sh

Versión systemd timer

# backup.service
[Unit]
Description=Daily backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# backup.timer
[Unit]
Description=Run daily backup at 3:00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

5.2 Ejecutar una tarea una sola vez, 5 minutos después del arranque

Con cron suele requerir trucos (ej. @reboot + sleep). Con systemd timer es directo:

# init-job.service
[Unit]
Description=Run custom init job after boot

[Service]
Type=oneshot
ExecStart=/usr/local/bin/init-job.sh
# init-job.timer
[Unit]
Description=Run init job 5 minutes after boot

[Timer]
OnBootSec=5min
AccuracySec=1min

[Install]
WantedBy=timers.target

Con esto, 5 minutos después del arranque se ejecutará init-job.service una sola vez.


6. ¿Cuál elegir?

6.1 Cuando seguir usando cron

  • Tienes muchas tareas cron ya funcionando y no necesitas integración con systemd
  • El servidor es pequeño con pocas tareas periódicas
  • Estás en un entorno que no usa systemd (algunos contenedores, BSD, sistemas muy antiguos)

6.2 Cuando prefieras systemd timer

  • La mayoría de tus servicios ya están gestionados por systemd
  • Quieres centralizar logs y estado en journal
  • Necesitas programar tareas basadas en tiempo relativo (X minutos después del arranque, X tiempo después de la última ejecución)
  • Requieres dependencias explícitas (ej. “solo después de que la red esté disponible”)
  • Buscas observabilidad consistente en CI/CD o entornos de producción

7. Consejos para migrar de cron a systemd timer

  1. Reúne la lista actual de tareas cron * crontab -l * /etc/crontab, /etc/cron.d/*
  2. Desglosa cada tarea en servicio + timer * ¿Qué ejecuta? → .service * ¿Cuándo? → .timer
  3. Convierte las expresiones cron a OnCalendar * 0 3 * * *OnCalendar=*-*-* 03:00:00 * */5 * * * *OnCalendar=*:0/5
  4. Prueba manualmente * systemctl start myjob.service * systemctl start myjob.timer y systemctl list-timers
  5. Desactiva el cron original * Una vez que el timer sea estable, comenta o elimina la entrada cron

8. Conclusión: coexistencia posible

En resumen:

  • cron sigue siendo un programador simple y portable
  • systemd timer ofrece gestión de servicios, observabilidad y flexibilidad en entornos modernos

No hay una única respuesta correcta. Si ya tienes cron funcionando, no es necesario migrar todo. Pero para nuevas tareas, especialmente aquellas que se benefician de dependencias y logs centralizados, systemd timer suele ser la mejor opción.

image