WittCodešŸ’»

Is Cron Outdated?

By

Cron jobs are great for automating tasks, but they also have their drawbacks. They lack granular control and can be difficult to debug. Find a better alternative.

Table of Contents šŸ“–

Cron

Historically, Cron has been the go-to tool for automating repetitive tasks, from running backups to clearing temporary files. This is because Cron jobs are lightweight and easy to set up. However, the logs for cron jobs are usually scattered, there's no built in mechanism for missed tasks, and it lacks integration with system services.

INFO: Cron logs are scattered and less structured, often found in /var/log/syslog.

Systemd Timers

A more modern alternative to cron jobs are systemd timers. Essentially, a timer triggers a corresponding service which defines the task to run. To demonstrate, lets create a systemd timer from the Cron job below. This Cron job prints "Hello from cron!" to /tmp/cron-log.txt every minute.

* * * * * echo "Hello from cron!" >> /tmp/cron-log.txt

To turn this into a systemd timer, we need to create a service file and a timer file. The service file defines what we want to run and the timer file specifies when and how the service should run.

[Unit]
Description=Print Hello World to Console

[Service]
ExecStart=/bin/echo "Hello from systemd!" >> /tmp/systemd-log.txt
[Unit]
Description=Run Hello World Service Every Minute

[Timer]
OnUnitActiveSec=1min
AccuracySec=1s
Persistent=true

[Install]
WantedBy=timers.target

Now lets start the service.

sudo systemctl start hello-world.service

We can also verify the status of both the timer and service to see if it is active and running:

systemctl status hello-world.timer
ā— hello-world.timer - Run Hello World Service Every Minute
   Loaded: loaded (/etc/systemd/system/hello-world.timer; enabled; vendor preset: enabled)
   Active: active (elapsed) since Mon 2025-01-13 16:12:57 UTC; 8s ago
  Trigger: n/a

We can also inspect the status and information about all timers.

systemctl list-timers --all
NEXT                         LEFT          LAST                         PASSED       UNIT                         ACTIVATES
Mon 2025-01-13 16:29:48 UTC  44s left      Mon 2025-01-13 16:28:27 UTC  35s ago      hello-world.timer            hello-world.service
Mon 2025-01-13 19:54:27 UTC  3h 25min left Mon 2025-01-13 09:49:52 UTC  6h ago       motd-news.timer              motd-news.service
Tue 2025-01-14 05:59:29 UTC  13h left      Mon 2025-01-13 05:59:29 UTC  10h ago      systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.servi
Tue 2025-01-14 06:22:01 UTC  13h left      Mon 2025-01-13 06:37:26 UTC  9h ago       apt-daily-upgrade.timer      apt-daily-upgrade.service
Tue 2025-01-14 10:54:33 UTC  18h left      Mon 2025-01-13 14:54:44 UTC  1h 34min ago certbot.timer                certbot.service

We can then use journalctl to inspect the logs of the service.

journalctl -u hello-world.service 
-- Logs begin at Sat 2024-01-20 20:47:33 UTC, end at Mon 2025-01-13 16:35:54 UTC. --
Jan 13 16:21:41 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:22:42 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:22:42 blog.wittcode.com echo[30992]: Hello from systemd! >> /tmp/systemd-log.txt
Jan 13 16:23:43 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:24:44 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:24:44 blog.wittcode.com echo[31472]: Hello from systemd! >> /tmp/systemd-log.txt
Jan 13 16:25:45 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:26:25 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:26:25 blog.wittcode.com echo[31877]: Hello from systemd! >> /tmp/systemd-log.txt
Jan 13 16:27:26 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:28:27 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:28:48 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:29:48 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:30:49 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:30:49 blog.wittcode.com echo[492]: Hello from systemd! >> /tmp/systemd-log.txt
Jan 13 16:31:50 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:32:51 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:32:51 blog.wittcode.com echo[990]: Hello from systemd! >> /tmp/systemd-log.txt
Jan 13 16:33:52 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:33:52 blog.wittcode.com echo[1233]: Hello from systemd! >> /tmp/systemd-log.txt
Jan 13 16:34:53 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:35:54 blog.wittcode.com systemd[1]: Started Print Hello World to Console.
Jan 13 16:35:54 blog.wittcode.com echo[1707]: Hello from systemd! >> /tmp/systemd-log.txt

All of this only scratches the surface of systemd timers. They also provide error handling, dependency management, granular timing and more. I suggest you look into these before deciding to use Cron jobs next.