Skip to content

Timers

Scope: scheduling with systemd instead of cron — a timer unit paired with a service unit, with real firings verified.

The pair

A timer never runs anything itself. It activates a service (same name, .timer ↔ .service), usually a Type=oneshot. The lab's pair, shipped in examples/:

mere-log.service — the work: append a timestamp line to a file, then exit. Oneshot is exactly right: run, succeed, done.

mere-log.timer:

[Unit]
Description=Run mere-log.service every 15 seconds

[Timer]
OnBootSec=10
OnUnitActiveSec=15
AccuracySec=1

[Install]
WantedBy=timers.target
  • OnBootSec=10 — first run 10s after boot.
  • OnUnitActiveSec=15 — then every 15s after the last activation. (For wall-clock schedules there's OnCalendar= — below.)
  • AccuracySec=1 — systemd otherwise batches wakeups (default accuracy is a minute) to save power; for a demo, precision beats thrift.
  • Timers get enabled like services, attached to timers.target.
sudo systemctl start mere-log.timer     # or enable --now for keeps
systemctl list-timers
NEXT                        LEFT LAST                          PASSED UNIT           ACTIVATES
Fri 2026-10-16 18:32:27 CDT  14s Fri 2026-10-16 18:32:12 CDT 23ms ago mere-log.timer mere-log.service

and the proof, three ticks fifteen seconds apart:

tick 2026-10-16T23:32:12+00:00
tick 2026-10-16T23:32:27+00:00
tick 2026-10-16T23:32:43+00:00

OnCalendar: the cron dialect

OnCalendar=Mon..Fri 06:30
OnCalendar=daily            (00:00)
OnCalendar=*-*-01 04:00     (the 1st, at 04:00)

systemd-analyze calendar "Mon..Fri 06:30" expands any expression and shows the next firing — run it before deploying a schedule, because calendar expressions are write-only in every tool ever made.

Why not cron?

Cron still works and this guide won't pretend otherwise. Timers win on specifics:

  • The work is a service — so it gets the journal (journalctl -u mere-log.service), dependencies, restart policy, sandboxing, everything in this guide, for free. Cron jobs get an email nobody reads.
  • Persistent=true — a timer whose time passed while the machine was off fires at next boot. Cron just skips it. (The laptop-backup problem from the Backups guide has a native answer here.)
  • One list: systemctl list-timers --all shows every schedule on the box, next and last, in one table — versus hunting through five crontabs and an /etc/cron.d.

Keep cron for what it's good at; reach for timers when the job is yours and deserves supervision.