Setting Up Systemd Timers

A guide to setting up systemd timers as a modern, flexible, and efficient alternative to cron jobs.

Systemd timers are a powerful alternative to cron jobs for scheduling tasks. They offer greater flexibility and better integration into the systemd ecosystem. In this article, I’ll show you how to set up and use systemd timers.

What is a systemd timer?

A systemd timer is a systemd unit that schedules another service to run at specific times. Timers replace cron jobs and offer advantages such as:

  • Better logging with journalctl.
  • The ability to define dependencies and startup conditions.
  • More precise control over execution times.

Basic Structure

A systemd timer consists of two files:

  1. Service file: Defines what should be executed.
  2. Timer file: Defines when the service should be executed.

Both files are stored in the /etc/systemd/system/ directory.

Step 1: Create the Service File

The service file describes the action to be executed. For example, let’s run a script located at /usr/local/bin/backup.sh.

Create a file named backup.service:

1
nano /etc/systemd/system/backup.service

Content of the file:

1
2
3
4
5
6
7
[Unit]
Description=Backup Script
After=network.target

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

Explanation:

  • [Unit]: Describes the unit. Description provides a short description, and After=network.target ensures the network is available before the service starts.
  • [Service]: Defines the service. Type=oneshot means the service performs a one-time action. ExecStart specifies the command or script to be executed.

Step 2: Create the Timer File

The timer file defines when the service should be executed. Create a file named backup.timer:

1
nano /etc/systemd/system/backup.timer

Content of the file:

1
2
3
4
5
6
7
8
9
[Unit]
Description=Run Backup Script Daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Explanation:

  • [Unit]: Similar to the service file, this provides a short description.
  • [Timer]: Defines the scheduling.
    • OnCalendar=daily: Runs the service daily at midnight. Other time specifications can also be used (see below).
    • Persistent=true: Ensures the timer runs after a restart, even if it was missed during downtime.
  • [Install]: WantedBy=timers.target ensures the timer is activated at system startup.

Time Specifications for systemd Timers

The time for a systemd timer is defined in the timer file using the OnCalendar option. Systemd supports a flexible and powerful time format for both simple and complex schedules. Here are some examples and explanations:

Basic Format

The general format for OnCalendar is:

1
OnCalendar=YYYY-MM-DD HH:MM:SS
  • YYYY: Year (e.g., 2025)
  • MM: Month (01 to 12)
  • DD: Day (01 to 31)
  • HH: Hour (00 to 23)
  • MM: Minute (00 to 59)
  • SS: Second (00 to 59)

You can use wildcards (*) to make certain parts flexible.

Common Time Specifications

  1. Hourly (every full hour):

    1
    
    OnCalendar=hourly
    

    Equivalent to: *-*-* *:00:00

  2. Daily at midnight:

    1
    
    OnCalendar=daily
    

    Equivalent to: *-*-* 00:00:00

  3. Weekly (Sunday at midnight):

    1
    
    OnCalendar=weekly
    

    Equivalent to: Sun *-*-* 00:00:00

  4. Monthly (1st day of the month at midnight):

    1
    
    OnCalendar=monthly
    

    Equivalent to: *-*-01 00:00:00

  5. Yearly (January 1st at midnight):

    1
    
    OnCalendar=yearly
    

    Equivalent to: *-01-01 00:00:00

Custom Time Specifications

  1. Every day at 15:30:

    1
    
    OnCalendar=*-*-* 15:30:00
    
  2. Every Monday at 08:00:

    1
    
    OnCalendar=Mon *-*-* 08:00:00
    
  3. Every first day of the month at 12:00:

    1
    
    OnCalendar=*-*-01 12:00:00
    
  4. Every last day of the month at 23:59:

    1
    
    OnCalendar=*-*-28..31 23:59:00
    

    (Systemd automatically detects the last day of the month, e.g., 28, 30, or 31.)

  5. Every second day at 06:00:

    1
    
    OnCalendar=*-*-1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 06:00:00
    

Repetitions and Intervals

  1. Every 5 minutes:

    1
    
    OnCalendar=*:0/5
    

    (Runs at minute 0, 5, 10, 15, etc., every hour.)

  2. Every 2 hours:

    1
    
    OnCalendar=*-*-* 0/2:00:00
    

    (Runs at 00:00, 02:00, 04:00, etc.)

  3. Every 15 minutes:

    1
    
    OnCalendar=*:0/15
    

    (Runs at 00, 15, 30, and 45 minutes past the hour.)

  4. Every 10 days:

    1
    
    OnCalendar=*-*-01,11,21 00:00:00
    

Step 3: Reload Systemd

After creating the files, reload the systemd configuration:

1
systemctl daemon-reload

Step 4: Enable and Start the Timer

Enable the timer so it starts automatically at system boot:

1
systemctl enable --now backup.timer

The --now flag starts the timer immediately. If you want to start it manually, omit --now and use:

1
systemctl start backup.timer

Step 5: Verify the Timer

To ensure the timer is set up correctly, check its status:

1
systemctl status backup.timer

Optional Commands and Tips

  1. List all timers:

    1
    
    systemctl list-timers --all
    

    This displays all active and inactive timers, including their next and last execution times.

  2. Check service status:

    1
    
    systemctl status backup.service
    
  3. View service logs:

    1
    
    journalctl -u backup.service
    
  4. Stop or disable a timer:

    • Stop the timer:
      1
      
      systemctl stop backup.timer
      
    • Disable the timer:
      1
      
      systemctl disable backup.timer
      

Conclusion

Systemd timers are a modern and powerful alternative to cron jobs. They offer precise control, better logging, and seamless integration into the system. With the steps described above, you can easily set up and manage your own timers.