DEV Community

Leon Nunes
Leon Nunes

Posted on

Systemd Timers as a Cron Alternative

Today I want to write about Systemd timers, I recently had to convert sketchy While True scripts to systemd timers, and the performance improvement was a huge plus point.

Yes I get it people hate systemd, it may not be perfect but it definitely works for this particular use case. It is however, quite intimidating at first since there are so many options, and you also need to create two files per use-case.

So let me break it down, You need to create a service file and a timer file, you can also use template files, however that is out of the scope of this article.

So let's get started.

First, open up your terminal or text editor and paste.

[Unit]
Description=Runs a command and logs to journalctl
Wants=randomprogram.timer

[Service]
Type=oneshot
ExecStart=python -c 'print("Hello world")'

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Save this file in /etc/systemd/system/randomprogram.service
Lets break this down

  • Description - This contains generic information
  • Wants=randomprogram.timer - As per the Systemd manual, units listed in this option will be started if the configuring unit is basically if you start the service with systemctl start randomprogram.service the timer will also be started.
  • Type=oneshot - There are a lot of different types you can specify here(simple, exec, forking, oneshot, dbus, notify or idle). Reading man systemd.service would be far better here.
  • WantedBy=multi-user.target - This is equivalent to runlevel 2 in sysvinit.

After we finish this, its now time to create a timer service. Save this file in /etc/systemd/system/randomprogram.timer

[Unit]
Description=Runs timer program systemd journal
After=httpd.service
Requires=randomprogram.service

[Timer]
Unit=randomprogram.service
#OnCalendar=*-*-* *:*:12
OnUnitActiveSec=12s
AccuracySec=1us

[Install]
WantedBy=timers.target
Enter fullscreen mode Exit fullscreen mode

Lets break this down again. I'll take the new options.

  • After=httpd.service - Start the timer after httpd.service this was for my use case
  • Requires=randomprogram.service - If this unit gets activated, the units listed will be activated as well.
  • OnCalendar=*-*-* *:*:12 - The format for this is DayOfWeek Year-Month-Day Hour:Minute:Second where DayOfWeek can be omitted, this will run at the 12th second for every minute(like cron), however the dev's here needed it to run every 12 seconds.
  • OnUnitActiveSec=12s - Defines a timer relative to when the unit the timer unit is activating was last activated.
  • AccuracySec=1us - Specify the accuracy the timer shall elapse with. Defaults to 1min(we needed high accuracy too...)

A detailed documentation on Systemd Timers is present here

And now systemctl start randomprogram.timer
Journalctl logs

That's it folks, I'm pretty sure there are a lot of things you can do with systemd, but I'm still learning and there is a lot of things I still don't know. So feel free to drop a comment about this post.

Top comments (0)