Systemd Timers

Systemd is the standard service manager and init process for modern Linux. It unifies many system utilities under a new suite of tools, daemons, and APIs. If you want to enable services to start at boot, and restart themselves when they crash, you use systemd.

Systemd also provides a way to run commands on a schedule, just like the venerable crond. This feature is known as “timers” in systemd. Let’s look at how they work.

Check Active Timers

First off, it’s likely that your Linux distribution, or a package you’ve installed, has already created some systemd timers. You can list them like this.

sudo systemctl list-timers

This will yield a list of active timers.

# some output elided
NEXT        LEFT     LAST  PASSED   UNIT             ACTIVATES 
Sat 2018..  3h 38min Fri.. 20h ago  logrotate.timer  logrotate...
Sat 2018..  3h 38min Fri.. 20h ago  man-db.timer     man-db.ser..
Sat 2018..  3h 38min Fri.. 20h ago  shadow.timer     shadow.ser..
Sat 2018..  15h left Fri.. 8h ago   systemd-tmpfiles systemd-tm..

5 timers listed.
Pass --all to see loaded but inactive timers, too.

We show 4 active timers, one per row. The columns are fairly self-explanatory. “NEXT” and “LEFT” are human-readable times when the timer will fire next. “LAST” and “PASSED” are the opposite: the date and time of the last timer run. “UNIT” and “ACTIVATES” indicate the two files systemd requires for a timer. We should consider these two files next.

Required Files

To make a working systemd timer, at least two files are required. The first is a file with a .timer extension. The other is usually some kind of service file, commonly with a .service extension. Importantly, they must both share a name, with only the extensions being different. So for an example.timer a corresponding example.service must exist.

Note that, in systemd terms, both files are known as “unit files”. The thing that makes timers special are 1) their .timer extension and 2) the fact that they can activate other unit files. This is the meaning of the “UNIT” and “ACTIVATES” columns above.

Both kinds of unit files can usually be found at two common paths

You will probably want to create your timers under /etc/systemd/system.

Example foo.timer and foo.service

To demonstrate a timer that runs 15 minutes after boot and then once every 30 minutes the system is active, see the following OnBootSec= and OnUnitActiveSec= configuration option under [Timer].

# /etc/systemd/system/foo.timer
[Unit]
Description=An example timer

[Timer]
OnBootSec=15min
OnUnitActiveSec=30min

[Install]
WantedBy=timers.target

Note that this timer file does not specify a command to run. For that, we need the corresponding foo.service file.

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
ExecStart="/usr/local/bin/example-timer.sh"
ExecReload=/bin/kill $MAINPID
KillMode=mixed
KillSignal=SIGQUIT

[Install]
WantedBy=multi-user.target

The actual command we want scheduled is under the [Unit] section, specifically the ExecStart= attribute.

Starting a Timer

To kick off the timer we defined above, run the following command.

sudo systemctl start foo.timer

The timer should now be visible with systemctl list-timers. And the logs for the associated service will be visible with journalctl.

sudo journalctl --unit=foo

Further Reading

We’ve only seen the absolute minimum examples of timers and unit files. In particular, there is another flavor of timer to run things on a predefined date, like Christmas, your birthday, etc. This is possible with the OnCalendar= attribute. See the complete documentation for details.