Platform schedule guide
systemd Timer and OnCalendar Guide
Replace cron with systemd timers. Learn OnCalendar syntax, timer and service units, timezone handling, Persistent catch-up, AccuracySec, randomized delay, validation, and operations.
Platform behavior reviewed against the official documentation on August 5, 2026.
- Format
- OnCalendar, not cron
- Default timezone
- System local zone
- Missed-run option
- Persistent=true
- Default accuracy
- 1 minute
Overview
A systemd timer schedules another systemd unit, normally a service with the same base name. Calendar timers use OnCalendar expressions; monotonic timers use durations such as OnBootSec and OnUnitActiveSec. Neither form is a literal cron expression.
Timers integrate with service dependencies, resource controls, journal logs, status inspection, and missed-run catch-up. That makes them a strong replacement for machine-local cron when the host already uses systemd.
OnCalendar can express seconds, dates, ranges, lists, repetition, weekdays, and timezones. Validate every expression on the target system with systemd-analyze calendar because supported syntax can depend on the installed systemd version.
systemd OnCalendar format
A full calendar event can include weekday, date, time, and timezone. Omitted date components default to every date, and omitted seconds default to :00. Shorthands such as hourly, daily, weekly, monthly, and yearly improve readability.
Use OnCalendar for wall-clock events. Use OnBootSec, OnActiveSec, OnUnitActiveSec, or OnUnitInactiveSec when the requirement is a duration relative to boot, activation, or the service lifecycle.
[weekday] [year-month-day] [hour:minute:second] [timezone]
Mon..Fri *-*-* 09:00:00 Europe/Istanbul
*-*-* *:00/5:00 UTC
*-*-01 02:30:00| Field | Position | Values | Platform note |
|---|---|---|---|
| Weekday | Optional | Mon-Sun, lists, ranges | English names; Mon..Fri is a continuous range. |
| Date | Optional | year-month-day | * matches any component; lists, ranges, and repetition are available. |
| Time | Optional | hour:minute:second | Seconds default to 00 when omitted. |
| Timezone | Optional | UTC or IANA zone | Without it, the system local timezone is used. |
Copyable schedule examples
At the top of every hour
hourly
Every five minutes
*-*-* *:00/5:00
Weekdays at 09:00 in the system timezone
Mon..Fri *-*-* 09:00:00
Every Sunday at 02:00 UTC
Sun *-*-* 02:00:00 UTC
First day of every month at midnight
*-*-01 00:00:00
January, April, July, and October 1 at midnight
quarterly
Complete service and timer units
Create matching .service and .timer files. The timer activates backup.service, while the service owns the command, user, security controls, and completion status.
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly application backup
[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/application-backup
# /etc/systemd/system/backup.timer
[Unit]
Description=Run application backup every night
[Timer]
OnCalendar=*-*-* 02:17:00 UTC
Persistent=true
AccuracySec=1min
RandomizedDelaySec=5min
[Install]
WantedBy=timers.targetDeployment checklist
- Validate the expression with systemd-analyze calendar and inspect several next occurrences.
- Run systemctl daemon-reload, then start a manual systemctl start backup.service test.
- Enable the schedule with systemctl enable --now backup.timer.
- Inspect systemctl list-timers, systemctl status backup.timer, and journalctl -u backup.service.
Timezone, accuracy, and missed runs
An OnCalendar expression uses the system local timezone unless it ends with UTC or an installed IANA timezone such as Europe/Istanbul. Putting the timezone in the expression makes the unit portable across hosts with different local settings.
Calendar events follow the selected timezone’s civil-time rules, so DST can make intervals shorter or longer. Use systemd-analyze calendar with the exact expression on the target version and avoid ambiguous transition times for non-repeatable work.
AccuracySec defaults to one minute and allows systemd to coalesce wakeups. RandomizedDelaySec deliberately spreads work over a window. Persistent=true causes one immediate catch-up activation when at least one calendar event was missed while the timer was inactive; it does not replay every missed occurrence.
systemd-analyze calendar 'Mon..Fri *-*-* 09:00:00 Europe/Istanbul'
systemctl list-timers --all
journalctl -u backup.service --since todayLimits and platform behavior
- Not cron syntax
- Do not paste a five-field cron expression into OnCalendar. Convert the intent into systemd calendar syntax.
- Version-dependent features
- Newer systemd releases add syntax and timer controls. Validate on the oldest supported host instead of relying on a desktop version.
- Activation, not a shell line
- The timer activates a unit. Put commands, environment, user identity, and hardening in the associated service.
- One missed-run catch-up
- Persistent=true catches up with an activation if one or more runs were missed; it does not enqueue one execution for each missed timestamp.
Production gotchas
Assuming exact timing
AccuracySec and randomized delay affect activation time. Set them deliberately, but keep jobs correct even if the process starts late.
Testing only the timer
Start the service directly before enabling the timer. This separates command, permission, and environment failures from scheduling failures.
Relative timer drift
OnUnitActiveSec is relative to activation, not a fixed wall-clock schedule. Pick a monotonic or calendar timer based on the actual requirement.
Environment mismatch
A service does not inherit an interactive shell environment. Use absolute paths and declare required Environment or EnvironmentFile values.
Frequently asked questions
Is systemd OnCalendar the same as cron syntax?
No. OnCalendar uses systemd calendar event syntax. It can express weekdays, full dates, times, seconds, and timezones, but a five-field cron string must be converted.
How do I catch up a missed systemd timer?
Set Persistent=true on an OnCalendar timer. When the timer becomes active, systemd triggers the service if at least one occurrence was missed while inactive.
What timezone does a systemd timer use?
OnCalendar uses the system local timezone unless the expression specifies UTC or an installed IANA timezone.
How do I test an OnCalendar expression?
Run systemd-analyze calendar followed by the quoted expression. It normalizes the schedule and prints upcoming occurrences.