Timers are systemd unit files whose name ends in
.timer that control
.service files or events. Timers can be used as an alternative to cron (read #As a cron replacement). Timers have built-in support for calendar time events, monotonic time events, and can be run asynchronously.
Timers are systemd unit files with a suffix of
.timer. Timers are like other unit configuration files and are loaded from the same paths but include a
[Timer] section. The
[Timer] section defines when and how the timer activates. Timers are defined as one of two types:
- Monotonic timers activate after a time span relative to a varying starting point. There are number of different monotonic timers but all have the form of:
OnActiveSecare common monotonic timers.
- Realtime timers (a.k.a. wallclock timers) activate on a calendar event (like cronjobs). The option
OnCalendar=is used to define them.
.timer file, a matching
.service file exists (e.g.
.timer file activates and controls the
.service file. The
.service does not require an
[Install] section as it is the timer units that are enabled. If necessary, it is possible to control a differently-named unit using the
Unit= option in the timer's
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service
No changes to service unit files are needed to schedule them with a timer. The following example schedules
foo.service to be run with a corresponding timer called
A timer which will start 15 minutes after boot and again every week while the system is running.
[Unit] Description=Run foo weekly and on boot [Timer] OnBootSec=15min OnUnitActiveSec=1w [Install] WantedBy=timers.target
A timer which starts once a week (at 12:00am on Monday). It starts once immediately if it missed the last start time (option
Persistent=true), for example due to the system being powered off:
[Unit] Description=Run foo weekly [Timer] OnCalendar=weekly Persistent=true [Install] WantedBy=timers.target
The format controlling
OnCalendar events uses the following format when more specific dates and times are required:
DayOfWeek Year-Month-Day Hour:Minute:Second. An asterisk may be used to specify any value and commas may be used to list possible values. Two values separated by
.. may be used to indicate a contiguous range. In this example the service is run the first four days of each month at 12:00 PM, but only if that day is also on a Monday or a Tuesday. More information is available in
OnCalendar=Mon,Tue *-*-01..04 12:00:00
Transient .timer units
One can use
systemd-run to create transient
.timer units. That is, one can set a command to run at a specified time without having a service file. For example the following command touches a file after 30 seconds:
# systemd-run --on-active=30 /bin/touch /tmp/foo
One can also specify a pre-existing service file that does not have a timer file. For example, the following starts the systemd unit named
someunit.service after 12.5 hours have elapsed:
# systemd-run --on-active="12h 30m" --unit someunit.service
man systemd-run for more information and examples.
As a cron replacement
Although cron is arguably the most well-known job scheduler, systemd timers can be an alternative.
The main benefits of using timers come from each job having its own systemd service. Some of these benefits are:
- Jobs can be easily started independently of their timers. This simplifies debugging.
- Each job can be configured to run in a specific environment (see the
- Jobs can be attached to cgroups.
- Jobs can be set up to depend on other systemd units.
- Jobs are logged in the systemd journal for easy debugging.
Some things that are easy to do with cron are difficult to do with timer units alone.
- Complexity: to set up a timed job with systemd you create two files and run a couple
systemctlcommands. Compare that to adding a single line to a crontab.
- Emails: there is no built-in equivalent to cron's
MAILTOfor sending emails on job failure. See the next section for an example of setting up an equivalent using
You can set up systemd to send an e-mail when a unit fails - much like Cron does with
MAILTO. First you need two files: an executable for sending the mail and a .service for starting the executable. For this example, the executable is just a shell script using
#!/bin/bash /usr/bin/sendmail -t <<ERRMAIL To: $1 From: systemd <root@$HOSTNAME> Subject: $2 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 $(systemctl status --full "$2") ERRMAIL
Whatever executable you use, it should probably take at least two arguments as this shell script does: the address to send to and the unit file to get the status of. The .service we create will pass these arguments:
[Unit] Description=status email for %I to user [Service] Type=oneshot ExecStart=/usr/local/bin/systemd-email address %i User=nobody Group=systemd-journal
user is the user being emailed and
address is that user's email address. Although the recipient is hard-coded, the unit file to report on is passed as an instance parameter, so this one service can send email for many other units. At this point you can start
email@example.com to verify that you can receive the emails.
Then simply edit the service you want emails for and add
OnFailure=status-email-user@%n.service to the
%n passes the unit's name to the template.
Using a crontab
Several of the caveats can be worked around by installing a package that parses a traditional crontab to configure the timers.
If you like crontabs just because they provide a unified view of all scheduled jobs,
systemctl can provide this. See #Management.
- systemd.timer man page on freedesktop.org
- Fedora Project wiki page on systemd calendar timers
- Gentoo wiki section on systemd timer services
- systemd-cron-next — tool to generate timers/services from crontab and anacrontab files
- systemd-cron — provides systemd units to run cron scripts; using systemd-crontab-generator to convert crontabs