Run a Script N Minutes After Boot with systemd (Without cron)

Deepak Prasad
Tested on RHEL 10.2 (Coughlan) — vm1.lab.example
Package systemd 257-23.el10_2.2
Applies to Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux
Privilege sudo or root
Scope Pair a oneshot service with a timer using OnBootSec for a boot delay, enable only the timer, inspect list-timers, and read the script output file. Does not cover calendar schedules or cron migration.
Related guides systemd timers
Run script at boot after network
crontab command
Create a systemd service
systemctl command

When you need a script to run several minutes after boot — not at the first second of multi-user.target — use two unit files: a timer that waits and a service that runs your script.

text
boot
delayed-boot-task.timer   (waits 5 minutes)
delayed-boot-task.service
your script

The .timer decides when to run. The .service decides what to run.


Create the script

Write a script that logs when the timer fires:

bash
sudo tee /usr/local/sbin/delayed-boot-task.sh <<'EOF'
#!/bin/bash
echo "time=$(date -Is) delayed_boot_task ran" >> /var/log/delayed-boot-task.log
EOF

Make it executable:

bash
sudo chmod 755 /usr/local/sbin/delayed-boot-task.sh

Create the service unit

Create /etc/systemd/system/delayed-boot-task.service:

ini
[Unit]
Description=Run delayed boot task once

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/delayed-boot-task.sh

You do not enable this service directly. The timer starts it when the delay expires, so only the .timer file needs an [Install] section.

Do not put a [Timer] section here. A [Timer] section belongs only in a .timer unit; putting it in a .service file produces an Unknown section 'Timer' warning or error and the timer settings are ignored.


Create the timer unit

Create /etc/systemd/system/delayed-boot-task.timer:

ini
[Unit]
Description=Run delayed boot task five minutes after boot

[Timer]
OnBootSec=5min
Unit=delayed-boot-task.service

[Install]
WantedBy=timers.target

OnBootSec=5min means five minutes after machine boot time. It is measured from boot, not from when you enable the timer. Change 5min to any supported span (90s, 10min, 1h 30min, and so on).


Reload and enable the timer

Reload unit definitions after creating both files:

bash
sudo systemctl daemon-reload

Enable the timer — not the service:

bash
sudo systemctl enable delayed-boot-task.timer

Sample output:

output
Created symlink '/etc/systemd/system/timers.target.wants/delayed-boot-task.timer' → '/etc/systemd/system/delayed-boot-task.timer'.

Plain enable schedules the timer for future boots. It does not start the timer in the current boot unless you also run systemctl start delayed-boot-task.timer or systemctl enable --now delayed-boot-task.timer.


Verify the next trigger

Reboot, then check when the timer will fire:

bash
systemctl list-timers delayed-boot-task.timer --no-pager

Sample output shortly after boot:

output
NEXT                        LEFT          LAST PASSED UNIT                     ACTIVATES
Fri 2026-08-21 11:19:43 IST 4min 48s left -    -      delayed-boot-task.timer  delayed-boot-task.service

1 timers listed.

The LEFT column is the countdown until your script runs.

After five minutes, the same command shows the timer as elapsed and lists a LAST time instead of NEXT.


Confirm the script ran

Read the log file the script writes:

bash
sudo cat /var/log/delayed-boot-task.log

Sample output:

output
time=2026-08-21T11:19:43+05:30 delayed_boot_task ran

Use the timestamp to confirm which run you are looking at.


Troubleshooting

Symptom Likely cause Fix
Unknown section 'Timer' [Timer] inside .service Move schedule to .timer file
Service runs immediately during testing Timer started after OnBootSec= elapsed Expected for current boot; full delay applies when the timer starts during boot on the next cycle
Timer enabled but nothing on current boot enable alone does not start the timer Use systemctl start or enable --now to activate in the running boot
Timer active but no script Name mismatch Set Unit= in timer or match basenames
No second run during the same boot OnBootSec= fires once per boot Expected — use OnUnitActiveSec= in systemd timers guide for repeated runs

References

Summary

A boot delay needs two files: the timer holds OnBootSec= and the [Install] section; the service holds ExecStart=. Enable only the timer.

Use systemctl list-timers to watch the countdown, then confirm the script log after the trigger fires. For repeating schedules or calendar times, see the full systemd timers guide.


Frequently Asked Questions

1. Why do I get Unknown section Timer in my service file?

A Timer section belongs only in a .timer unit. Putting it in a .service file produces an Unknown section Timer warning or error and the timer settings are ignored.

2. Should I enable the service or the timer?

Enable the timer. The service unit in this guide has no Install section because the timer starts it. systemctl enable delayed-boot-task.timer is the correct step.

3. What is the difference between OnBootSec and OnStartupSec?

OnBootSec is measured from when the machine booted. OnStartupSec is measured from when the service manager started; on the system manager they are usually equivalent, but OnBootSec is the common choice for boot delays.

4. What if I start the timer after the OnBootSec= time has already passed?

If you start the timer after that point has already passed in the current boot, systemd fires it immediately. Plain systemctl enable only schedules it for future boots. Use systemctl start or enable --now to activate it in the running boot.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration