Systemd timers

Linux

1. Cron vs Systemd timers

To automate tasks,in a Linux environment, cron is the seasoned veteran that has been around for decades, while systemd timers are the modern, integrated alternative.
At their core, both tools do the same thing: they run a command at a specific time. However, their architecture differs significantly.

  • Cron: Relies on a single daemon (crond) that checks a configuration file (the crontab) once a minute. If a time matches, it executes the command in a subshell.

  • Systemd Timers: Are unit files (.timer) that trigger service files (.service). The timer handles the "when," and the service handles the "what."

cron is easier to write for a quick one-liner, systemd timers offer professional-grade features that make them superior for critical tasks:

  1. Better debugging With cron, if a job fails, you often have to dig through messy mail files or hope you redirected stderr to a log. With systemd, you can simply run journalctl -u myjob.service to see exactly why it failed, including the full output of the script.

  2. catching up on missed runs If a computer is turned off when a cron job is supposed to run, that job is simply missed. Systemd timers have a Persistent flag. If the timer was missed, it will trigger immediately once the system boots back up.

  3. Dependency Awareness Cron will just blindly attempt the command and fail if the environment isn't ready. Systemd timers can wait for specific conditions. For example, tell a timer only to run once the network is up, or only if a specific disk is mounted.

  4. Randomized Delays With cron , on large systems, all workstations will try to update at the same time causing bottlenecks on a central update server. Systemd allows for 'RandomizedDelaySec'. This is great for preventing "thundering herds"

  5. Resource Management We can easily cap a systemd service so it never uses more than 500MB of RAM or 10% of our CPU. 'systemctl set-property’ command and set the 'CPUQuota' property within the systemd service unit file

When to Use Which? Use Cron for very simple, user-level tasks on a machine that stays on 24/7 (like a server) where you don't care about granular logs.

Use Systemd Timers for everything else—especially system-critical tasks, scripts on laptops that might be asleep, or processes that need strict resource limits.

2. Systemd timers

Systemd timers are categorized into two main types based on how they calculate their "alarm" time. While they both use the same .timer file format, the way we define the [Timer] section determines their behavior.

2.1 Realtime timers (OnCalendar Timers)

They work similarly to cron tasks, and are very useful for automating tasks with precise time conditions. Example, execute a task every day at 6:00 pm :

[Timer]
OnCalendar=*-*-* 18:00

'OnCalendar=Mon,Tue --* 11:00:00' every monday and tuesday at 11:00 am.

2.2 Monotonic Timers (Relative)

These timers trigger based on a "stopwatch" that starts ticking after a specific event. They are much more flexible than cron because they don't care what the actual date is. These timers are useful for tasks that need to be repeated regularly for maintenance processes, such as checking the status of services every 10 minutes after the system starts up. Common directives include:

  • OnBootSec=: Triggers a certain amount of time after the machine finishes booting.
  • OnUnitActiveSec=: Triggers relative to when the service was last started. This is perfect for "run this every 15 minutes" logic.
  • OnUnitInactiveSec=: Triggers relative to when the service last finished. This prevents jobs from overlapping if one run takes longer than expected.
  • OnStartupSec=: Triggers relative to when systemd itself first started.
2.3 Transient Timers

Beyond the file-based timers mentioned above, there are also Transient Timers. These are created on the fly using the systemd-run command. They aren't stored in permanent configuration files and vanish once the system reboots or the task finishes.

Example:

systemd-run --on-active=1h /usr/bin/my-script.sh 

This creates a one-time timer that runs in 1 hour.

2.4 Which one to choose?
we want to... Use this type Directive example
Run a backup every night at midnight Realtime OnCalendar=daily
Run a cleanup script 10 mins after boot Monotonic OnBootSec=10min
Poll an API every 30 seconds Monotonic OnUnitActiveSec=30s
Ensure a task runs 1 hour after the previous one finished Monotonic OnUnitInactiveSec=1h

Previous Post