v5.0
live available
practices guide 15 Oct 2026

Five schedulers, one missed window, and which of them remembers

Stopped a timer for three and a half minutes so it would miss four runs, then started it again. One configuration made up the missed run. The other had no idea it had been away.

By Purvansh Parmar Checked 2026-10-21 Read 7 min Entries 5

A job that must run daily will eventually not run. The laptop was shut, the drive was unplugged, the box was rebooting at exactly the wrong minute. What happens next is decided entirely by whether your scheduler wrote down that the job was due, and most of them do not keep that record anywhere at all, which is why the question of what to do about a missed run never even reaches you. I stopped two timers that differ by one line of configuration, let them miss four runs each, and started them again. One of them made the run up. The other had no record that anything had been missed, because it keeps no record of anything at all.

How this was checkedBuilt two systemd user timers that differ in exactly one line, Persistent=true against Persistent=false, both firing every minute. Stopped both for three and a half minutes so each missed four scheduled fires, then started them together and watched the log. The persistent one fired immediately on restart. The other waited for the next scheduled minute as though nothing had happened. Only the persistent timer had written a stamp file, which is the whole mechanism visible on disk.

What I compared on

01 systemd timer, Persistent=true

A calendar timer that writes a stamp file recording the last time its unit was triggered.

Wins
It is the only thing tested here that recovers a missed window without anyone writing code for it, and the recovery is one line of unit file. The stamp under the timers data directory makes the state inspectable.
Loses
One catch up run for four missed fires is right for a daily report and wrong for anything that was supposed to happen four times. It also only applies to OnCalendar timers, so monotonic ones get nothing.
1 catch up run for 4 missed firesfired 34 s early1 stamp file

02 systemd timer, Persistent=false

The same calendar timer with the stamp turned off, which is the default unless you ask otherwise.

Wins
This is teh correct setting for anything where a late run is worse than no run: a cache warm, a notification, a health probe. Running a stale job twenty minutes late can be its own incident.
Loses
It is the default, and the default silently loses work. Nothing in the output of list-timers tells you the job was due while the machine was down, because nothing recorded that it was due.
0 of 4 missed fires recovered0 stamp filesthe default

03 cron

The scheduler already on every box, which fires a job if the machine happens to be awake at the right minute.

Wins
It is everywhere, it needs no unit files, and a crontab line is readable by anyone. For a server that is genuinely always on, the missing feature never comes up.
Loses
There is no catch up and no way to add one, because there is no record to compare against. On a laptop or anything that sleeps, a daily job is a job that runs on the days you were lucky.
0 state files0 catch upfires only if awake

04 anacron

The companion built specifically for machines that are not always on, driven by elapsed days rather than wall clock times.

Wins
It is the right shape for the problem and it is already installed: it exists precisely because the machine was off, and it compares elapsed days against a stamp rather than hoping you were awake.
Loses
A period of one day is the floor, so anything hourly cannot use it, and the delay plus the randomisation means you do not control when inside the day it lands. It is a catch up mechanism with no precision.
1 day minimum period3 timestamp files5 minute post boot delay

05 A marker file and a retry window

Schedule the job every hour across a window, and have it exit immediately if a marker says today is already done.

Wins
It works on plain cron, it needs no new software, and it turns a single point in time into a window, which is what actually fixes the laptop case. The marker is also the audit trail that cron does not keep.
Loses
The window only helps inside one day: if the machine is down for the whole window, every retry is lost and the next day starts fresh with no memory of it. That is the failure this pattern does not solve.
7 chances per day1 marker file0 recovery across days

Side by side

Records last runRecovers a missed windowGranularity
systemd Persistent=trueyes, stamp fileyes, one catch up runany calendar
systemd Persistent=falsenonoany calendar
cronnonoone minute
anacronyes, timestampyes, on next bootone day
marker plus retry windowyes, markerwithin the day onlyone hour

Verdict

Use a systemd timer with Persistent=true for anything that has to happen rather than happen on time. It was the only thing in this test that noticed it had been away, it recovered the window without a line of code, and the one catch up run for four missed fires is the right behaviour for a daily job. Keep cron for the always on server where the question never arises. The thing to be clear eyed about is that Persistent=false is the default, so a timer written without thinking about this has precisely the same failure mode as the cron line it replaced, with more configuration.

Sources