Understanding Systemd Timers

Systemd is a software suite that provides a standard process for controlling what programs run when a Linux system boots up. It starts the core programs running and a journal of system activity, the network stack, a cron-style job scheduler, user logins, and many other jobs.

Systemd timers are a part of this systmed suite and they enable us to schedule tasks to be executed at specified times or intervals, similar to cron jobs but with more features and tight integration with the rest of the systemd ecosystem.

Systemd Timers or Cron Jobs

  1. Cron is more of a stand-alone thing whereas systemd timers are part of systemd. Therefore systemd timers can be used only on distributions with systemd systems while cron jobs can be used on distributions either with systemd systems or non-systemd systems.

  2. Systemd timers have additional features such as support for complex calendar-based events, built-in support for catching up on missed jobs, a built-in mechanism for dependency management or condition checks before job execution, and integration with systemd’s journal which provides centralized and unified logging etc.

  3. Additional features of systemd timers come with added complexity. Therefore, systemd timers are a bit more involved meaning more to learn while cron jobs are much simpler to understand and implement.

Which one to use depends on the complexity of the task and which of the two solutions is a better fit for your project on a case-by-case basis.

Components of Systemd Timers

To create a systemd timer two files are required: a .timer file to schedule the task and a .service file for the task.

  • Timer units are the actual timer definitions. They define when and how often a task should be executed. The timer units have a .timer extension and are typically stored in the /etc/systemd/system directory. An example of weather-report.timer unit file is given below.

  • Service units are the tasks that are executed when the timer is triggered. Service units have a .service extension and are typically stored in the /etc/systemd/system directory. An example of weather-report.service unit file is provided below.

When you have a .service file with the same name as the .timer file in the directory, with the only difference being the file extension, systemd automatically considers them to be related. Usually, for each timer, there is a corresponding service file that gets executed when the timer triggers.

Types of Timers

  • Real-time timers are based on the actual real-world clock time. They can be set to trigger at specific times, such as "every day at 2:00 AM".

  • Monotonic timers are based on a timer relative to a certain point, such as "15 minutes after boot".

Hands-on Exercise Overview

Understanding systemd timers involve knowing how to create and manage them. This hands-on exercise shows how to create a systemd timer that will run the wall command automatically on a specific schedule.

Hands-on Exercise

  1. Create a new weather-report.service unit file:

     sudo vim /etc/systemd/system/weather-report.service
    
  2. Copy and paste the following code into the file and save it:

     [Unit]
     Description=Weather Report Service
     After=network-online.target
     Wants=network-online.target
    
     [Service]
     ExecStart=/bin/sh -c 'sudo wall $(curl wttr.in?format=3)'
    
     [Install]
     WantedBy=default.target
    

    This simple file executes the wall command, which stands for "write to all". The wall command sends a message to all users currently logged into the system and the message is supposed to be the output of curl wttr.in?format=3, which queries the wttr.in service for weather information in a brief format. This can be particularly useful for system administrators who need to notify users about system maintenance, reboots, or other important events.

  3. Refresh systemd so that it’s aware of the fact we added a new service file:

     sudo systemctl daemon-reload
    
  4. Now, when we want to send a weather report to every user on the system, all we need to do is start the systemd service for it:

     sudo systemctl start weather-report.service
    

  5. Create a new weather-report.timer unit file the type of which will be a timer:

     sudo vim /etc/systemd/system/weather-report.timer
    
  6. Copy and paste the following code into the file and save it:

     [Unit]
     Description=Weather Report Service
    
     [Timer]
     OnCalendar=Mon..Fri 08:32
     Persistent=true
    
     [Install]
     WantedBy=timers.target
    

    Under the timer section, we have OnCalendar here. We’re giving it a range starting with Monday and ending with Friday. Also, we’re setting it for 08:32 am, which means the timer will trigger weather-report.service file every weekday at 08:32 am.

    If the server is down for any reason the timer won’t trigger. Enabling the Persistent=true option, allows the task to run once the server starts up next in case the OnCalendar time is missed.

    💡
    The timer will look for a file name that’s the same as its own but with a .service extension instead of a .timer extension. Therefore we don’t tell the timer which service file to start, it already knows what it is looking for. All we have to do is match the naming scheme.

    In the install section, targets are another type of unit file, and when you link them like this, the current file will inherit specific characteristics from the target.

  7. Refresh systemd once more so that it knows we added a new timer unit file:

     sudo systemctl daemon-reload
    
  8. Finally, start and enable the timer with one single command:

     sudo systemctl enable --now weather-report.timer
    
  9. Check the status of your timer:

     systemctl status weather-report.timer
    

References:

  1. Automate Your Tasks with systemd Timers: A Step-by-Step Guide

  2. How to use systemd timers (cronjob alternative)

  3. Understanding Systemd Services

  4. systemd.time format

  5. Systemd timers onCalendar (cron) format explained