Back

You Don't Love systemd Timers Enough: the Case Against cron
SiTech AI Team3 min read

You Don't Love systemd Timers Enough: the Case Against cron

An engineer argues that the cron daemon is the wrong tool for scheduled work in 2026, and walks through what systemd timers do better: predictable environments, visible execution history and readable schedules.

Anyone who schedules work on Linux reaches for cron, and the word has become a metonym for scheduled execution of every kind. Writing on his blog in May 2026, the engineer behind tjll.net argues that the literal cron daemon, and its more modern cousins, is the wrong tool in 2026 — and that the systemd timer deserves more affection than it gets.

The case against cron

His objections are practical rather than ideological. Ambiguous $PATH settings make cron script execution hard to predict. Standard output and standard error often disappear into a black hole, or land in the host's mail system, which is rarely what anyone wants. Execution history is difficult to follow and interrogate. And the scheduling grammar, a point of pride for some, is not easy to read: an expression such as 01,31 04,05 1-15 1,6 * takes real effort to decode. Timers, he writes, solve all of these problems and more.

A service, a timer and a schedule

A systemd timer is a unit type that schedules another unit, usually a service. The article's worked example is a service with a one-in-ten chance of shutting the machine down, paired with a timer file sharing the same name stem in /etc/systemd/system, since a timer's default Unit= setting picks the matching .service. Starting the .timer puts it on the clock but does not run the target; enabling it makes it come up at boot through the WantedBy=timers.target install target. Two details catch people out: ExecStart does not run through a shell by default, so pipes do not work as written, and it inherits no environment variables beyond the system manager's defaults.

Calendar events and time spans

The biggest conceptual leap from cron is that systemd offers two kinds of schedule. One is the familiar calendar event — daily, or its fully qualified form *-*-* 00:00:00 — and the other is a period of time measured against a previous event, such as OnBootSec=1h with OnUnitActiveSec=1h, which runs an hour after boot and then an hour after every run. The second form often matches the real intent: a job that clears a temporary directory gains little from firing immediately after boot, and a bot polling an API every fifteen minutes on the clock contributes to a traffic spike that a time-span schedule avoids. The author points to the systemd.time manual as the first reference and to systemd-analyze calendar, which validates and explains expressions and can even decode classic cron wildcards.

He also singles out features cron cannot offer: list-timers, which prints one table of what runs next and what ran last; WakeSystem=, which resumes a suspended machine to run a job; FixedRandomDelay= and RandomizedOffsetSec=, which spread execution to avoid thundering-herd spikes; and Persistent=, which triggers a missed run as soon as the timer is active again, useful for configuration-management check-ins on a laptop that has been switched off. User-level timers run through systemctl --user are equally valid, though the install target sometimes needs to be default.target. The clock still has to be right, and timedatectl timesync-status shows whether it is.

SiTech

SiTech — AI-powered web development

We build fast, modern websites and bring AI into real business workflows. Have a project or a question? We'd love to help.