SYSTEMD.TIMER(5)

๐Ÿ’– NAME ๐Ÿ’–

okay so bestie, systemd.timer is literally the manual for Timer unit configuration ๐Ÿ’… โ€” the whole glow-up guide for .timer files. periodt.


โœจ SYNOPSIS โœจ

timer.timer

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

A unit configuration file whose name ends in .timer is carrying all the deets about a timer that systemd itself controls and supervises โ€” it's giving timer-based activation energy โฐโœจ. fr fr.

This man page lists the configuration options that are specific to this unit type. For the common options that every unit configuration file gets, go read systemd.unit(5) ๐Ÿ‘‘. Those shared config items live in the generic [Unit] and [Install] sections. The timer-specific stuff lives in the [Timer] section.

For each timer file, a matching unit file must exist, describing the unit to activate when the timer elapses ๐Ÿซถ. By default, a service with the same name as the timer (minus the suffix) is what gets activated. Example: a timer file foo.timer activates a matching service foo.service. The unit to activate can be controlled with Unit= (see below ๐Ÿ‘‡).

Note that if the unit to activate is already active at the moment the timer elapses, it is not restarted โ€” it's just simply left running ๐Ÿ’€. There is literally no concept of spawning new service instances in this case. Because of that, services with RemainAfterExit=yes set (which stick around continuously even after the service's main process has exited) are usually not suitable for activation via repetitive timers, since they'll only be activated once and then stay around forever ๐Ÿ™ˆ. Target units, which by default do not deactivate on their own, can be activated repeatedly by timers if you set StopWhenUnneeded=yes on them. That makes the target unit get stopped immediately after its activation, if it isn't a dependency of another running unit. iconic.

๐Ÿ”— AUTOMATIC DEPENDENCIES ๐Ÿ”—

Implicit Dependencies

The following dependencies are implicitly added:

  • Timer units automatically gain a Before= dependency on the service they're supposed to activate โฑ๏ธ.

Default Dependencies

The following dependencies are added unless DefaultDependencies=no is set:

  • Timer units will automatically have dependencies of type Requires= and After= on sysinit.target, a dependency of type Before= on timers.target, plus Conflicts= and Before= on shutdown.target, to make sure they're stopped cleanly before system shutdown ๐Ÿงน. Only timer units involved with early boot or late system shutdown should disable the DefaultDependencies= option.
  • Timer units with at least one OnCalendar= directive acquire a pair of additional After= dependencies on time-set.target and time-sync.target, so they don't get started before the system clock has been correctly set ๐Ÿ•ฐ๏ธโœจ. See systemd.special(7) for details on these two targets.

โš™๏ธ OPTIONS โš™๏ธ

Timer unit files may include [Unit] and [Install] sections, which are described in systemd.unit(5) ๐Ÿ“–.

Timer unit files must include a [Timer] section, which carries information about the timer it defines. The options specific to the [Timer] section of timer units are the following:

  • OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= โ€” defines monotonic timers relative to different starting points ๐ŸŒˆ:

Table 1. Settings and their starting points

  • OnActiveSec= โ€” Defines a timer relative to the moment the timer unit itself is activated.
  • OnBootSec= โ€” Defines a timer relative to when the machine was booted up. In containers, for the system manager instance, this is mapped to OnStartupSec=, making both equivalent.
  • OnStartupSec= โ€” Defines a timer relative to when the service manager was first started. For system timer units this is very similar to OnBootSec= as the system service manager is generally started very early at boot. It's primarily useful when configured in units running in the per-user service manager, as the user service manager is generally started on first login only, not already during boot.
  • OnUnitActiveSec= โ€” Defines a timer relative to when the unit the timer unit is activating was last activated.
  • OnUnitInactiveSec= โ€” Defines a timer relative to when the unit the timer unit is activating was last deactivated.

Multiple directives may be combined, of the same and of different types, in which case the timer unit will trigger whenever any of the specified timer expressions elapse ๐Ÿ’ฅ. For example, by combining OnBootSec= and OnUnitActiveSec=, it's possible to define a timer that elapses in regular intervals and activates a specific service each time. Moreover, both monotonic time expressions and OnCalendar= calendar expressions may be combined in the same timer unit ๐Ÿ‘ฏ.

The arguments to these directives are time spans configured in seconds. Example: "OnBootSec=50" means 50s after boot-up. The argument may also include time units. Example: "OnBootSec=5h 30min" means 5 hours and 30 minutes after boot-up. For details about the syntax of time spans, see systemd.time(7) ๐Ÿ“š.

If a timer configured with OnBootSec= or OnStartupSec= is already in the past when the timer unit is activated, it will immediately elapse and the configured unit is started ๐Ÿƒโ€โ™€๏ธ. This is not the case for timers defined in the other directives.

These are monotonic timers, independent of wall-clock time and timezones ๐ŸŒ. If the computer is temporarily suspended, the monotonic clock generally pauses too ๐Ÿ˜ด. Note that if WakeSystem= is used, a different monotonic clock is selected that continues to advance while the system is suspended and thus can be used as the trigger to resume the system โฐ๐Ÿ’ค.

If the empty string is assigned to any of these options, the list of timers is reset (both monotonic timers and OnCalendar= timers, see below), and all prior assignments will have no effect ๐Ÿงผ.

Note that timers do not necessarily expire at the precise time configured with these settings, as they are subject to the AccuracySec= setting below โณ.

  • OnCalendar= โ€” defines realtime (i.e. wallclock) timers with calendar event expressions ๐Ÿ“…โœจ. See systemd.time(7) for more information on the syntax of calendar event expressions. Otherwise, the semantics are similar to OnActiveSec= and related settings.

Note that timers do not necessarily expire at the precise time configured with this setting, as it is subject to the AccuracySec= setting below โณ.

May be specified more than once, in which case the timer unit will trigger whenever any of the specified expressions elapse ๐Ÿ’ซ. Moreover, calendar timers and monotonic timers (see above) may be combined within the same timer unit.

If the empty string is assigned to any of these options, the list of timers is reset (both OnCalendar= timers and monotonic timers, see above), and all prior assignments will have no effect ๐Ÿงผ.

Note that calendar timers might be triggered at unexpected times if the system's realtime clock is not set correctly ๐Ÿ˜ฌ. Specifically, on systems that lack a battery-buffered Realtime Clock (RTC) it might be wise to enable systemd-time-wait-sync.service to ensure the clock is adjusted to a network time source before the timer event is set up. Timer units with at least one OnCalendar= expression are automatically ordered after time-sync.target, which systemd-time-wait-sync.service is ordered before.

When a system is temporarily put to sleep (i.e. system suspend or hibernation) the realtime clock does not pause ๐Ÿ˜ด. When a calendar timer elapses while the system is sleeping it will not be acted on immediately, but once the system is later resumed it will catch up and process all timers that triggered while the system was sleeping ๐ŸŒ…. Note that if a calendar timer elapsed more than once while the system was continuously sleeping, the timer will only result in a single service activation. If WakeSystem= (see below) is enabled, a calendar time event elapsing while the system is suspended will cause the system to wake up (under the condition the system's hardware supports time-triggered wake-up functionality) โฐ๐Ÿ”ฅ.

Added in version 197.

  • AccuracySec= โ€” okay so this is the how on-time do you actually need this knob. Defaults to 1min. Your timer gets scheduled to go off inside a lil window: it opens at whatever time you gave in OnCalendar=, OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec= or OnUnitInactiveSec=, and it closes AccuracySec= later. Inside that window the expiry lands at a host-specific, randomized, but stable spot that's synced across all your local timer units. Why? โœจPower savingsโœจ โ€” it lets the machine suppress pointless CPU wake-ups. Want max accuracy? Set it to 1us. Heads up though: the timer is still at the mercy of the timer slack from systemd-system.conf(5)'s TimerSlackNSec= setting โ€” peep prctl(2) for the tea. And for power purposes, set this as high as you can get away with and as low as you actually need. ๐Ÿ’…

Also real talk: this is primarily a power-saving option that lets CPU wake-ups get coalesced. Do not confuse it with RandomizedDelaySec= (right below) which adds a random value to the next elapse time and does the literal opposite โ€” it stretches timer events over a longer stretch to squash workload spikes. For the full rundown on how the two play together, keep reading, bestie. ๐Ÿซถ

Added in version 209.

  • RandomizedDelaySec= โ€” delays the timer by a randomly picked, evenly distributed amount of time between 0 and the value you give it. Defaults to 0, meaning no randomized delay at all. Each timer unit rolls this delay randomly before each iteration, unless you mess with FixedRandomDelay= (below). The delay gets added on top of the next determined elapsing time โ€” or the service manager's startup time, whichever is later. ๐ŸŽฒ

This is the move when you want to spread out a bunch of similarly configured timer events over some interval so they don't all fire at the exact same moment and cause resource congestion on your local system. Very demure, very mindful. ๐ŸŒธ

Now the relationship with AccuracySec= above: that one lets the service manager coalesce timer events inside a time range to minimize wakeups, while this one does the opposite โ€” it stretches events over an interval so it's unlikely they all fire together. Use both? First the randomized delay gets added, then the result may get shifted further to coalesce with other timer events on the system. Since AccuracySec= defaults to 1 minute and RandomizedDelaySec= to 0, the default vibe is very much coalescing. If you want to optimally stretch events over a range, set AccuracySec=1us and give RandomizedDelaySec= some higher value. ๐Ÿ”ฅ

Added in version 229.

  • FixedRandomDelay= โ€” takes a boolean. When enabled, the randomized delay from RandomizedDelaySec= is chosen deterministically and stays stable across all firings of the same timer โ€” even if the manager restarts. The delay is derived from the machine ID, the manager's user identifier, and the timer unit's name. So basically each timer gets its own unique fixed offset, which reduces the jitter in firings of an individual timer while still dodging the "everyone fires at once" problem with other similarly configured timers. Iconic behavior honestly. ๐Ÿ‘‘

Only does anything if RandomizedDelaySec= is not 0. Defaults to false.

Added in version 247.

  • RandomizedOffsetSec= โ€” offsets the timer by a stable, randomly-selected, evenly distributed amount of time between 0 and the value you give it. Defaults to 0, meaning no offset. The offset is chosen deterministically and is derived the same way as FixedRandomDelay= (see above). It gets added on top of the next determined elapsing time. This one only does anything for timers configured with OnCalendar=, and it can be combined with RandomizedDelaySec=. ๐ŸŒˆ

Much like RandomizedDelaySec=, it's for distributing timer events so they don't all go off at once. But this one is most useful for preventing resource congestion on a remote service from a whole fleet of similarly-configured clients. Unlike RandomizedDelaySec=, it applies its offset with zero regard for manager startup time โ€” which keeps the periodicity of your configured OnCalendar= events intact across manager restarts. Chef's kiss. โœจ

Example time, bestie: say you run a backup service and you've got a fleet of laptops that all wanna make backups weekly. To spread the load on the backup service, each laptop should randomly pick a weekday to upload. You could do this by setting OnCalendar= to "weekly" and configuring RandomizedDelaySec= of "5 days" with FixedRandomDelay= enabled. But say some laptop randomly lands on a delay of 4 days. If that laptop gets restarted more often than that, the timer will never fire โ€” on each fresh boot the 4 day delay restarts and won't finish before the next shutdown. ๐Ÿ˜ญ So instead you should use RandomizedOffsetSec=, which maintains the configured weekly cadence of timer events, even across reboots.

Added in version 258.

  • DeferReactivation= โ€” takes a boolean. When enabled, the timer schedules the next elapse based on the trigger unit entering inactivity, instead of the last trigger time. Most noticeable when the service unit takes longer to run than the timer interval. With this on, the timer schedules the next elapse based on when the service finishes running, so it'll have to wait until the next realtime elapse time to trigger. Otherwise, default behavior is the timer unit immediately triggers again the second the service finishes โ€” because the timer schedules the next elapse based on the previous trigger time, and since the interval is shorter than the service runtime, that elapse is already in the past, so it just fires right away. ๐Ÿ’€

Only does anything if a realtime timer is specified with OnCalendar=. Defaults to false.

Added in version 257.

  • OnClockChange=, OnTimezoneChange= โ€” these take boolean arguments. When true, the service unit gets triggered when the system clock (CLOCK_REALTIME) jumps relative to the monotonic clock (CLOCK_MONOTONIC), or when the local system timezone gets modified. You can use these alone or in combination with other timer expressions (see above) in the same timer unit. Both default to false.

Added in version 242.

  • Unit= โ€” the unit to activate when this timer elapses. The argument is a unit name whose suffix is not .timer. If you don't specify it, it defaults to a service with the same name as the timer unit, minus the suffix (see above). Highly recommend you name the activated unit and the timer unit identically except for the suffix. Keep it matchy-matchy. ๐ŸŽ€
  • Persistent= โ€” takes a boolean. If true, the time the service unit was last triggered gets stored on disk. When the timer is activated, the service unit is triggered immediately if it would have been triggered at least once while the timer was inactive. That triggering is still subject to the delay from RandomizedDelaySec=. Super useful for catching up on missed runs when the system was powered down. Note it only has an effect on timers configured with OnCalendar=. Defaults to false.

Run systemctl clean --what=state ... on the timer unit to delete the timestamp file this option maintains from disk. In particular, do this before uninstalling a timer unit. See systemctl(1) for details.

Added in version 212.

  • WakeSystem= โ€” takes a boolean. If true, an elapsing timer will cause the system to resume from suspend, if it's suspended and the system supports it. Note that this only makes sure the system wakes at the right times โ€” it does not suspend it again after the work is done. Defaults to false.
Heads up: this functionality requires privileges, so it's generally only available in the system service manager. ๐Ÿ‘‘

Also note that the behaviour of monotonic clock timers (configured with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, see above) changes depending on this option. If false, it uses a monotonic clock that's paused during system suspend (CLOCK_MONOTONIC). If true, it uses a different monotonic clock that keeps advancing during suspend (CLOCK_BOOTTIME) โ€” see clock_getres(2) for the deets.

Added in version 212.

  • RemainAfterElapse= โ€” takes a boolean. If true, a timer stays loaded and its state stays queryable even after it elapsed and the associated unit (configured with Unit=, see above) deactivated again. If false, an elapsed timer unit that can't elapse anymore gets unloaded once its associated unit deactivates again. Turning this off is especially useful for transient timer units. And it matters when you start a timer repeatedly: if RemainAfterElapse= is on, starting the timer a second time does nothing. But if it's off and the timer unit was already unloaded, you can start it again, so the service can get triggered multiple times. Defaults to true.

Added in version 229.

Check systemd.unit(5), systemd.exec(5), and systemd.kill(5) for more settings. ๐Ÿ“š


โœจ SEE ALSO โœจ

Environment variables with details on the trigger get set for triggered units โ€” peep the "Environment Variables Set or Propagated by the Service Manager" section in systemd.exec(5) for more. ๐ŸŒŸ


And that's a wrap, bestie! ๐Ÿซถ This whole thing is from systemd 262.1, and it's the SYSTEMD.TIMER(5) page โ€” go schedule something iconic. ๐Ÿ’–โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms