Is Cron Outdated?
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.