Time Abbreviations
OnCalendar=[Time Abbreviations]
[Time Abbreviations] : minutely, hourly, daily, weekly, monthly, annually
These abbreviations will trigger the timer on 1st January, 00:00:00 by default.
Example: OnCalendar=daily
Common Units & Syntax
OnCalendar=[Day of Weeks] [Year]-[Month]-[Day] [Hour]:[Minute]:[Second]
Range(..)
Use to specify range
Example: If want trigger every weekday , insert Mon..Fri as [Day of Weeks]
Wildcards(*)
Use to present other characters
Example: If want trigger every day , insert *-*-* as [Year]-[Month]-[Day]
Commas(,)
Use to specify multiple
Example: If want trigger multiple times (8:00 AM, 12:00 PM, and 6:00 PM) in single day , insert 08,12,18 as [Hour]
Step values(/)
Syntax: [Any Parameters]/[Step]
Example: If want trigger every 15 mins, insert 00/15:00 as [Minute]
All common units & syntax can be combined.
Example: OnCalendar=Mon,Wed,Fri *-*-* 08..11,14..17:00/10:00
Run every 10 minutes, but only between 8:00 AM - 11:00 AM and 2:00 PM - 5:00 PM on Mon, Wed, Fri
Test Expression
systemd-analyze calendar "[Expression]"
Use systemd-analyze calendar to verify expression valid or not
Example: systemd-analyze calendar "Mon,Wed,Fri *-*-* 08..11,14..17:00/10:00"
OnBootSec=[Number][Units]
OnStartupSec=[Number][Units]
OnBootSec measures time elapsed since the OS kernel booted up.
OnStartupSec measures time since user login.
[Units]
s seconds
min minutes
h hours
d days
Example
OnBootSec=15min
Run 15 minutes after the system finishes booting
OnUnitActiveSec=[Number][Units]
OnUnitActiveSec triggers relative to when the target service unit was last activated.
[Recommended] Pairs with OnBootSec
Because if the target service has never been triggered yet, OnUnitActiveSec= has no starting baseline.
Example
OnBootSec=5min
OnUnitActiveSec=1h
Run 5 minutes after boot, then repeat every 1 hour after each activation.
[Unit Name] in .service and .timer are same.
Create .service unit file
sudo touch /etc/systemd/system/[Unit Name].service
Example: sudo touch /etc/systemd/system/Demo.service
Open .service unit file by vim
sudo vim /etc/systemd/system/Demo.service
Example: sudo vim /etc/systemd/system/Demo.service
Write content of .service unit file
Press Esc --> I to enter insert mode
[Unit]
Description=demo unit
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/[Output File Name].txt
Example:
[Unit]
Description=demo unit
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/output.txt
4. Save and exit
Esc --> :wq
5. Verify .service file content
cat /etc/systemd/system/[Unit Name].service
Example: cat /etc/systemd/system/Demo.service
6.Verify timer expression
systemd-analyze calendar [Expression]
Example: systemd-analyze calendar *:00/01
7. Create .timer unit file
sudo touch /etc/systemd/system/[Unit Name].timer
Example: sudo touch /etc/systemd/system/Demo.timer
8. Open .timer unit file by vim
sudo vim /etc/systemd/system/[Unit Name].timer
Example: sudo vim /etc/systemd/system/Demo.timer
9. Press I to enter insert mode
[Install] section define how system handle when run systemctl enable <unit-name>.timer.
WantedBy=timers.target means turn this timer on (WantedBy=timers.target) automatically when the system boots up. Then, when the schedule is reached (OnCalendar=), run the matching service.
[Unit]
Description=demo timer
[Timer]
OnCalendar=[Expression]
[Install]
WantedBy=timers.target
Example:
[Unit]
Description=demo timer
[Timer]
OnCalendar=*:00/01 // Equivalent to <*-*-* *:00/01:00> or <minutely>, means run every minute
[Install]
WantedBy=timers.target
10. Save and exit
Esc --> :wq
11. Verify .timer file content
cat /etc/systemd/system/[Unit Name].timer
Example: cat /etc/systemd/system/Demo.timer
12. Reload the systemd
systemctl daemon-reload
13.Enable the timer
sudo systemctl enable --now [Unit Name].timer
Example: sudo systemctl enable --now Demo.timer
14.Verify
systemctl status [Unit Name].service
systemctl status [Unit Name].timer
systemctl list-timers [Unit Name].timer
Example:
systemctl status Demo.service
systemctl status Demo.timer
systemctl list-timers Demo.timer
15. Display content of output file
watch ls -l /tmp/[Output File Name].txt
Press Ctrl+C to exit
Example: watch ls -l /tmp/output.txt
Every 2.0s: ls -l /tmp/output.txt localhost.localdomain: Mon Sep 21 15:07:14 2026
-rw-r--r--. 1 root root 0 Sep 21 15:07 /tmp/output.txt
16. Cleanup - Stop and disable the timer and service
systemctl stop [Unit Name].timer
systemctl disable --now [Unit Name].timer
systemctl stop [Unit Name].service
Example:
systemctl stop Demo.timer
systemctl disable --now Demo.timer
systemctl stop Demo.service
17. Cleanup - Delete file
rm -f /etc/systemd/system/[Unit Name].service
Example: rm -f /etc/systemd/system/Demo.service
rm -f /etc/systemd/system/[Unit Name].timer
Example: rm -f /etc/systemd/system/Demo.timer
rm -f /tmp/[Output File Name].txt
Example: rm -f /tmp/output.txt
17. Cleanup - Reload systemd
systemctl daemon-reload
Result
student@localhost:~$ sudo touch /etc/systemd/system/Demo.service
[sudo] password for student:
student@localhost:~$ sudo vim /etc/systemd/system/Demo.service
student@localhost:~$ cat /etc/systemd/system/Demo.service
[Unit]
Description=demo unit
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/output.txt
student@localhost:~$ systemd-analyze calendar *:00/01
Original form: *:00/01
Normalized form: *-*-* *:00/1:00
Next elapse: Mon 2026-09-21 15:02:00 +08
(in UTC): Mon 2026-09-21 07:02:00 UTC
From now: 25s left
student@localhost:~$ sudo touch /etc/systemd/system/Demo.timer
student@localhost:~$ sudo vim /etc/systemd/system/Demo.timer
student@localhost:~$ cat /etc/systemd/system/Demo.timer
[Unit]
Description=demo timer
[Timer]
OnCalendar=*:00/01
[Install]
WantedBy=timers.target
student@localhost:~$ systemctl daemon-reload
student@localhost:~$ sudo systemctl enable --now Demo.timer
Created symlink '/etc/systemd/system/timers.target.wants/Demo.timer' → '/etc/systemd/system/Demo.timer'.
student@localhost:~$ systemctl status syslog-check.service
Unit syslog-check.service could not be found.
student@localhost:~$ systemctl status Demo.service
○ Demo.service - demo unit
Loaded: loaded (/etc/systemd/system/Demo.service; static)
Active: inactive (dead) since Mon 2026-09-21 15:04:12 +08; 1s ago
Invocation: d8059d8136414cccaba987a73edb5d0f
TriggeredBy: ● Demo.timer
Process: 7297 ExecStart=/usr/bin/touch /tmp/output.txt (code=exited, status=0/SUCCESS)
Main PID: 7297 (code=exited, status=0/SUCCESS)
Mem peak: 1.1M
CPU: 44ms
Sep 21 15:04:12 localhost.localdomain systemd[1]: Starting Demo.service - demo unit...
Sep 21 15:04:12 localhost.localdomain systemd[1]: Demo.service: Deactivated successfully.
Sep 21 15:04:12 localhost.localdomain systemd[1]: Finished Demo.service - demo unit.
student@localhost:~$ systemctl status Demo.timer
● Demo.timer - demo timer
Loaded: loaded (/etc/systemd/system/Demo.timer; enabled; preset: disabled)
Active: active (waiting) since Mon 2026-09-21 15:03:32 +08; 59s ago
Invocation: 66cd0191a4e74a36ac1575d8480c008d
Trigger: Mon 2026-09-21 15:05:00 +08; 28s left
Triggers: ● Demo.service
Sep 21 15:03:32 localhost.localdomain systemd[1]: Started Demo.timer - demo timer.
student@localhost:~$ systemctl list-timers Demo.timer
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2026-09-21 15:05:00 +08 11s Mon 2026-09-21 15:04:12 +08 35s ago Demo.timer Demo.service
1 timers listed.
Pass --all to see loaded but inactive timers, too.
student@localhost:~$ watch ls -l /tmp/output.txt
student@localhost:~$ systemctl stop Demo.timer
student@localhost:~$ systemctl disable --now Demo.timer
Removed '/etc/systemd/system/timers.target.wants/Demo.timer'.
student@localhost:~$ systemctl stop Demo.service
student@localhost:~$ sudo rm -f /etc/systemd/system/Demo.service
[sudo] password for student:
student@localhost:~$ sudo rm -f /etc/systemd/system/Demo.timer
student@localhost:~$ sudo rm -f /tmp/output.txt
student@localhost:~$ systemctl daemon-reload