About this article
This article is created using an automated generation workflow leveraging generative AI. Based on the official manuals of systemd-analyze, systemd.timer, and systemd.time, we created a sample to inspect the next startup time in read-only mode. Execution verification on the target Ubuntu environment has not been performed yet.
Verification Status: 📘 Confirmed with official systemd manual, unverified on actual Ubuntu hardware
In Ubuntu*.timerEven after configuring this, the service may not run at the expected time. A common misconception isassuming that a correct calendar expression is equivalent to having the actual timer enabled.
systemd-analyze calendarBy using this, without enabling the timerOnCalendar=you can interpret expressions in the same format as and list the upcoming scheduled execution dates and times. FurthermorePersistent、AccuracySecchecking timezones separately can help reduce oversights.
Minimal Experiment: Calculating bi-hourly times
For example, if you want to execute at 00:05, 02:05, 04:05, …, 22:05 Japan Standard Time, write the calendar expression as follows.
[Timer] OnCalendar=*-*-* 00,02,04,06,08,10,12,14,16,18,20,22:05:00 Asia/Tokyo Persistent=false
This is a configuration example. Services and timers are not enabled yet.
Run the following command on Ubuntu.
systemd-analyze calendar --iterations=8 \ '*-*-* 00,02,04,06,08,10,12,14,16,18,20,22:05:00 Asia/Tokyo'
This operation does not requiresudoand will not start production services such as WordPress. It simply parses the date and time syntax and calculates the next eight scheduled triggers. The output dates and days of the week vary depending on when it is executed.
Original form: ... Asia/Tokyo Normalized form: ... Next elapse: (次の偶数時05分に相当する日時) Iter. #2: (さらに2時間後) ...
* The above is an example of display items and not a copy of actual device logs.
Change one place and observe
What I want to verify is the difference between every hour on the hour and every two hours.
# 毎時00分 systemd-analyze calendar --iterations=4 \ '*-*-* *:00:00 Asia/Tokyo' # 偶数時05分 systemd-analyze calendar --iterations=4 \ '*-*-* 00,02,04,06,08,10,12,14,16,18,20,22:05:00 Asia/Tokyo'
In the output of bothNext elapseandIter. #2Compare the intervals between. The former should be calculated at approximately 1-hour intervals, and the latter at approximately 2-hour intervals. This allows you to check whether the intended schedule is reflected in the expression without running the actual service.
The Daily-Code-Samples scriptcombines this verification intopreview-calendar.sh. You can pass any calendar expression as an argument.
bash preview-calendar.sh bash preview-calendar.sh '*-*-* 08:30:00 Asia/Tokyo'
The difference between "scheduled time is correct" and "it actually runs"
| What to investigate | What to check | What you can find out |
|---|---|---|
| Calendar expression syntax | systemd-analyze calendar | Next scheduled trigger time |
| Whether the timer is registered and enabled | systemctl list-timers --all | Currently managed timers |
| Unit definition | systemctl cat 名前.timer | Settings such as OnCalendar and Persistent |
| Recent service execution results | systemctl status 名前.service | Current process state and recent execution |
| Error details | journalctl -u 名前.service | Service logs |
Even if the calendar expression is correct, if the timer isinactiveordisabledis used, it typically will not execute automatically on schedule. Furthermore, even if the timer runs, the process will not complete if the service itself fails.
The following operation onlyreadsthe existing configuration. Replace the target name with the one you manage.
systemctl list-timers --all --no-pager systemctl cat example.timer systemctl show example.timer \ -p ActiveState -p Unit -p NextElapseUSecRealtime -p LastTriggerUSec journalctl -u example.service --no-pager -n 30
You should not specify a non-existent unit. Verify the actual timer name before adapting the command. Depending on your viewing permissions, some journal entries may not be readable.
What happens when Persistent is set to true?
Persistent=trueis a setting that allows timers based on OnCalendar to catch up upon restart or similar events if scheduled triggers were missed while the timer was stopped or inactive.
| Configuration | Main meaning | Practical consideration |
|---|---|---|
Persistent=false | Avoid setting it to unconditionally recover missed triggers while stopped | Easier to prevent unexpected delayed execution of tasks such as publishing or billing processes |
Persistent=true | Enables catching up on missed calendar executions that occurred while stopped | Verify whether unexpected executions occur immediately after recovery |
AccuracySec | Trigger time accuracy window | May not execute at the exact scheduled time |
A common misconception isPersistent=trueis to assume that "every missed item will be re-executed one by one." This is not guaranteed. A timer is a mechanism that starts a service and does not manage the number of unprocessed items in the processing queue or publication duplicates.
For example, if you post one blog entry every two hours, it is dangerous to post all six missed entries at once just because the server was down for 12 hours. Use settings that limit delayed firing for the timer, andensure the application side checks for "only today's items" or "a maximum of one item in this two-hour window".
If time zones differ
OnCalendar=*-*-* 08:30:00writing it this way means the host's time zone settings will apply. If the cloud server is set to UTC, it will not match 08:30 viewed from Japan.
timedatectl date '+%Y-%m-%d %H:%M:%S %Z' systemd-analyze calendar '*-*-* 08:30:00 Asia/Tokyo'
in a calendar formatAsia/TokyoBy writing it this way, you can explicitly define the time reference. However, if the server's clock synchronization itself is inaccurate, the actual operation will be off even if the calendar interpretation is correct.
AccuracySec and service processing time
OnCalendarEven if you specify a time inAccuracySec, there is no guarantee that it will match the specified second exactly due to accuracy margins or service startup waits. Check not only general Linux performance issues, but also the Unit settings.
In addition, whether the same service is already running and how long the service takes to execute are important operational conditions. Even if the timer schedule is set to 2-hour intervals, if the application is designed to retry indefinitely, it will not enforce a processing limit of once every 2 hours.
Time control = timer, target validity = application, execution result = logs or DBSeparating these responsibilities makes it easier to trace the root cause.
5 items to check in practice
OnCalendarCan it be evaluated withsystemd-analyze calendar?Is the time zone explicitly specified?
Is the timer itself active and does it have the next scheduled time?
PersistentandAccuracySecis this the intended behavior?Did you verify the termination state and logs of the service after it triggered?
Checking in this order allows you to distinguish between different causes: incorrect time specification, disabled timer, abnormal service termination, or zero actual business tasks processed.

