Systemd Timer units

I am trying to create some systemd units that are supposed to start scripts at certain intervals. With Cron, I used an expression like 0 3 */7 * * to start a job every 7 days at 3 a.m. That worked great. With OnCalendar, I have no idea how to implement "every 7 days". Or can I use OnUnitActiveSec here? Additional problem: The computer is not always on at the specified time. The job should therefore be repeated as soon as the computer is available again. I have set Persistent=true for this purpose. However, I suspect that OnUnitActiveSec is reset every time I restart the computer. Or does OnUnitActiveSec refer to the time when the unit was activated with systemctl enabled test.timer?

17 points · 13 comments · view on lemmy.world

13 Comments

HelloRoot@lemy.lol · 5 pts · 188d (3 replies)

OnCalendar is calendar-based, not interval-based.

Use a monotonic timer with OnUnitActiveSec=7d plus Persistent=true . This is not quite the same as your cron, because it can drift the day of ghe weak.

And no, it does not reset just because you reboot.

MoLoPoLY@discuss.tchncs.de · 3 pts · 188d

Shifting the day of the week is totally fine, since i only care about days between the job executions. Many thx, then i try my luck with this.

MoLoPoLY@discuss.tchncs.de · 2 pts · 179d (1 reply)

It seems that this doesn't work as expected. Please see my new post from today. I have found also the following issue https://github.com/systemd/systemd/issues/3107. According to this, a monotonic timer doesn't survive a reboot or power off. Please correct me, if I'm wrong.

If I understand this correctly, only a onCalendar type can be used here. That's a little bit annoying, but as of yet, I haven't found a way around this.

HelloRoot@lemy.lol · 1 pts · 178d

oh shit thats really weird systemd design...

nous@programming.dev · 5 pts · 188d (3 replies)

Note that you can use systemctl list-timers to see all active timers including when they will next run and when they last ran. This is very useful for seeing if you have set things up correctly.

There are multiple ways to do this as well. You can do

OnCalendar=Sun 03:00
Persistent=true

To run every Sunday at 3am. And will run immediately when activated if the last time was skipped due to the system being off. Think that is the closest to your cron job.

You can also

OnCalendar=weekly
Persistent=true

If you don't care when it will run. This is equivalent to Mon *-*-* 00:00:00.

MoLoPoLY@discuss.tchncs.de · 2 pts · 188d

Ahh even more possibility's. Many thx.

DeltaWingDragon@sh.itjust.works · 1 pts · 188d (1 reply)

Why does it say "Sun" if it runs on Saturday?

nous@programming.dev · 1 pts · 188d

Typo on my part.

oranki@sopuli.xyz · 3 pts · 188d (1 reply)

Would something like

OnCalendar=Wed *-*-* 03:00:00

Technically not the same as every 7 days, instead it's every Wednesday.

MoLoPoLY@discuss.tchncs.de · 3 pts · 188d

OK. I think 7 day was a slightly misleading schedule :-) My bad. But yes, you are right, for 7 days, this will work fine. But i think OnUnitActiveSec=7d is more flexible, when i change this to 12 days, 9 days and so on... I should learn to be more precise in my questions. Sorry.

AstralPath@lemmy.ca · 2 pts · 188d

This might interest you. https://crontab.guru/

adept@programming.dev · 2 pts · 188d

Check the man pages, starting with man systemd.time

MoLoPoLY@discuss.tchncs.de · 1 pts · 179d

Sorry, i have to ask again. I actually thought I had solved the problem. However, today I discovered that the jobs are overdue and have not been started for several days. When I display the timers with systemctl --user list-timers, I see that the NEXT column is empty::

NEXT LEFT LAST                         PASSED UNIT                  ACTIVATES              
-       - Sun 2026-02-01 20:01:48 CET       - backup.timer  backup.service

Since there is no NEXT date, the timer/service will probably not be restarted. The timer unit looks like this:

[Unit]
Description="Backup to remote"

[Timer]
OnUnitActiveSec=3d
Persistent=true

[Install]
WantedBy=default.target

As you can see, I am well over the 3 days. When I call systemctl --user status backup.timer, I get:

● backup.timer - "Backup to remote"
     Loaded: loaded (/home/username/.config/systemd/user/backup.timer; enabled; preset: enabled)
    Drop-In: /home/username/.config/systemd/user/backup.timer.d
     Active: active (elapsed) since Fri 2026-02-13 16:53:31 CET; 7min ago
 Invocation: 95ae3860c50a454b98078fc2ce3eb3c5
    Trigger: n/a
   Triggers: ● backup.service

To me, this looks perfectly "normal." The only thing that puzzles me is the Active line. Why is the current date (Fri 2026-02-13 16:53:31 CET) set there and not the date on which the job last ran (Sun 2026-02-01 20:01:48 CET)? The NEXT column fills up again when I start systemctl --user restart backup.service. The job is then executed immediately and the column is filled. However, after rebooting the laptop, the column is empty again and the job is no longer started at the given intervals.