Skip to content

systemd timer directives

Synopsis

# /etc/systemd/system/<NAME>.timer
[Unit]
Description=<one-line description>

[Timer]
OnCalendar=<calendar event> …
OnActiveSec=<time span>
OnBootSec=<time span>
OnStartupSec=<time span>
OnUnitActiveSec=<time span>
OnUnitInactiveSec=<time span>
AccuracySec=<time span>
RandomizedDelaySec=<time span>
FixedRandomDelay=yes|no
RandomizedOffsetSec=<time span>
DeferReactivation=yes|no
OnClockChange=yes|no
OnTimezoneChange=yes|no
Persistent=yes|no
WakeSystem=yes|no
RemainAfterElapse=yes|no
Unit=<unit>

[Install]
WantedBy=timers.target

<NAME> is the timer's name without its suffix.

Description

A timer unit (suffix .timer) makes systemd start another unit when a time is reached. By default it starts the service with the same name: <NAME>.timer starts <NAME>.service, which must exist. The timer itself contains no command.

If the unit to be started is still active when the timer elapses, systemd leaves it running and doesn't start a second instance.

Timer units use the same file syntax, search paths and [Unit] and [Install] sections as other units; see systemd unit directives. Unless DefaultDependencies=no is set, a timer gets Requires= and After= on sysinit.target, Before= on timers.target, and Conflicts= and Before= on shutdown.target; a timer with OnCalendar= is also ordered After= time-set.target and time-sync.target. A timer is also ordered Before= the unit it starts.

Timer units are a feature of the systemd service manager. OpenRC has no equivalent; on Gentoo with OpenRC, scheduled jobs use cron (see crontab syntax).

Checked against systemd 257 on Debian 13, AlmaLinux 10 and Rocky Linux 10, systemd 259 on Ubuntu 26.04 and systemd 262 on Arch Linux (November 2026).

[Timer] directives

When the timer elapses

Directive Value Elapses
OnCalendar= Calendar event At each wall-clock time matching the expression (see Calendar events)
OnActiveSec= Time span This long after the timer unit was started
OnBootSec= Time span This long after the machine booted
OnStartupSec= Time span This long after the service manager started; for system timers almost the same as OnBootSec=, for user timers relative to the start of the user's service manager
OnUnitActiveSec= Time span This long after the unit the timer starts was last activated
OnUnitInactiveSec= Time span This long after the unit the timer starts was last deactivated
OnClockChange= Boolean, default no When the system clock jumps relative to the monotonic clock
OnTimezoneChange= Boolean, default no When the system time zone changes
  • OnCalendar= defines a realtime timer; the On…Sec= directives define monotonic timers, which don't depend on the wall clock or time zone and normally pause while the system is suspended.
  • Every directive in the table may be given more than once, and realtime and monotonic directives may be combined in one timer. The timer elapses whenever any of them elapses.
  • Assigning an empty value to any of OnCalendar=, OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec= or OnUnitInactiveSec= clears all realtime and monotonic timers set before it (useful in drop-ins).
  • If the time given by OnBootSec= or OnStartupSec= is already in the past when the timer is started, the timer elapses immediately. This doesn't apply to the other monotonic directives.
  • A repeating interval is commonly written as OnBootSec= combined with OnUnitActiveSec=, for example "15 minutes after boot, then every hour".
  • If a calendar timer elapses while the system is suspended, it's handled once after resume, however many times it elapsed during the sleep.

Timing adjustments

Directive Default Effect
AccuracySec= 1min systemd may delay each elapse by up to this span, at a host-specific stable point, to group wake-ups of several timers. 1us gives the best accuracy
RandomizedDelaySec= 0 Delays each elapse by a random time between 0 and this span, chosen anew for each elapse. Counted from the scheduled time or from the service manager's start, whichever is later
FixedRandomDelay= no With RandomizedDelaySec=: the delay is derived from the machine ID, the user and the unit name, so it's the same on every elapse and after restarts (systemd 247 and later)
RandomizedOffsetSec= 0 OnCalendar= timers only: adds a stable offset between 0 and this span, derived like FixedRandomDelay=, independently of the service manager's start time, so the schedule's period is kept across reboots (systemd 258 and later: Ubuntu 26.04 and Arch, not Debian 13 or RHEL 10)
DeferReactivation= no OnCalendar= timers only: computes the next elapse from when the started unit became inactive, not from the last trigger, so a job that runs longer than the interval doesn't start again immediately after it finishes (systemd 257 and later)

When RandomizedDelaySec= and AccuracySec= are both in effect, the random delay is added first and the result may then be shifted by up to AccuracySec=. To spread elapses evenly over a range, set AccuracySec=1us together with RandomizedDelaySec=.

Behaviour

Directive Default Effect
Persistent= no OnCalendar= timers only: stores the time of the last trigger on disk; when the timer is started (for example at boot) and an elapse was missed while it was inactive, the unit is started immediately, subject to RandomizedDelaySec=
WakeSystem= no Resumes the system from suspend when the timer elapses, if the hardware supports it; also makes monotonic timers use a clock that keeps running during suspend. System timers only
RemainAfterElapse= yes Keeps an elapsed timer that can't elapse again loaded and queryable. With no, such a timer is unloaded once its unit has finished, which suits transient timers
Unit= <NAME>.service The unit to start; any unit type except .timer

systemctl clean --what=state <NAME>.timer removes the timestamp stored by Persistent=.

Calendar events

[WEEKDAYS] [YEAR-MONTH-DAY] [HOUR:MINUTE[:SECOND]] [TIMEZONE]
Part Syntax
Weekdays English names, abbreviated (Mon) or full (Monday), any case; lists with ,, ranges with .. (Mon..Fri). Optional: without it, every day matches
Date YEAR-MONTH-DAY. Omitted: *-*-*
Time HOUR:MINUTE[:SECOND]. Omitted: 00:00:00. Omitted seconds: :00
* Any value of that component
, List of values: 06,18:00
.. Range: 9..17:00
/N The value and every Nth value after it: *:0/15 (minute 0, 15, 30 and 45); also after a range
~ In the day field, counts back from the end of the month: *-02~03 is the third-last day of February
Seconds May have decimal fractions, rounded to 6 places
Time zone UTC, or an IANA time zone name such as Europe/Berlin. Omitted: the system's local time zone

A weekday together with a day of the month must match both: Fri *-*-1..7 12:00 is noon on the first Friday of each month.

Shorthand Normalised form
minutely *-*-* *:*:00
hourly *-*-* *:00:00
daily *-*-* 00:00:00
weekly Mon *-*-* 00:00:00
monthly *-*-01 00:00:00
quarterly *-01,04,07,10-01 00:00:00
semiannually *-01,07-01 00:00:00
yearly, annually *-01-01 00:00:00

Time spans

A time span is a number with a unit, or several such terms, which are added: 1h 30min, 90s, 2d. Spaces between terms may be omitted. A number without a unit means seconds in all the …Sec= directives above.

Unit Accepted forms
Microseconds usec, us, μs
Milliseconds msec, ms
Seconds seconds, second, sec, s
Minutes minutes, minute, min, m
Hours hours, hour, hr, h
Days days, day, d
Weeks weeks, week, w
Months months, month, M (30.44 days)
Years years, year, y (365.25 days)

Commands

Command Effect
systemctl list-timers [--all] [PATTERN] Lists timers with their next and last elapse; --all includes inactive timers
systemctl enable --now <NAME>.timer Starts the timer at boot (via timers.target) and now
systemctl start <NAME>.service Runs the job immediately, independently of the timer
systemctl status <NAME>.timer Shows the timer's state and next elapse
systemctl show <NAME>.timer -p TimersCalendar,TimersMonotonic,LastTriggerUSec,NextElapseUSecRealtime Shows the parsed schedule and trigger times as properties
systemd-analyze calendar [--iterations=N] 'EXPRESSION' … Normalises a calendar event and shows its next N elapses
systemd-analyze timespan 'SPAN' … Normalises a time span and shows it in microseconds
systemd-analyze verify <FILE> Checks unit files for errors
systemd-run --on-calendar='EXPRESSION' COMMAND Creates a transient timer and service for a command (also --on-active=, --on-boot=, --on-unit-active=)
journalctl -u <NAME>.service Shows the job's output from every run

Examples

Normalised forms and next elapses printed by systemd-analyze calendar (systemd 257 on Debian 13, on Saturday 7 November 2026 at about 13:27 UTC):

$ systemd-analyze calendar --iterations=2 'Mon..Fri 02:30'
  Original form: Mon..Fri 02:30
Normalized form: Mon..Fri *-*-* 02:30:00
    Next elapse: Mon 2026-11-09 02:30:00 UTC
       From now: 1 day 13h left
   Iteration #2: Tue 2026-11-10 02:30:00 UTC
       From now: 2 days left
$ systemd-analyze calendar '*:0/15'
  Original form: *:0/15
Normalized form: *-*-* *:00/15:00
    Next elapse: Sat 2026-11-07 13:30:00 UTC
       From now: 2min 16s left
$ systemd-analyze calendar '2026-12-25 08:00 Europe/Berlin'
  Original form: 2026-12-25 08:00 Europe/Berlin
Normalized form: 2026-12-25 08:00:00 Europe/Berlin
    Next elapse: Fri 2026-12-25 07:00:00 UTC
       From now: 1 month 17 days left
$ systemd-analyze timespan '1h 30min'
Original: 1h 30min
      μs: 5400000000
   Human: 1h 30min

A daily job at 02:30, caught up after downtime and spread over 10 minutes:

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=10min

A job 15 minutes after boot, then every 6 hours after it last started:

[Timer]
OnBootSec=15min
OnUnitActiveSec=6h

A timer that starts a differently named service:

[Timer]
OnCalendar=Sun 04:00
Unit=weekly-cleanup.service

A step-by-step example is in How to schedule a job with a systemd timer.

Files

Path Purpose
/etc/systemd/system/<NAME>.timer Timer units created by the administrator
/usr/lib/systemd/system/*.timer Timer units installed by packages
/var/lib/systemd/timers/stamp-<NAME>.timer Time of the last trigger of a system timer with Persistent=true (its modification time)
/etc/systemd/system/timers.target.wants/ Symbolic links created by systemctl enable for timers with WantedBy=timers.target
~/.config/systemd/user/<NAME>.timer A user's own timers, managed with systemctl --user

See also

  • systemd.timer(5), systemd.time(7), systemd.unit(5), systemd.special(7), systemd-analyze(1), systemd-run(1)
  • systemd.timer, latest upstream version and systemd.time (check the "Added in version" notes against your installed version with systemctl --version)