cron @reboot: run a script at startup (and why it sometimes does not)
One line in your crontab and a script runs every time the machine starts. When it silently does nothing, it is almost always one of the same five things.
The basic line
crontab -e
# then add:
@reboot /home/me/bin/start.sh >> /home/me/start.log 2>&1
Use the full path to the script and make it executable (chmod u+x, see chmod explained). The redirect sends output and errors to a log, which is the single most useful thing when it does not work. You can check what any cron line means in the cron explainer, which also understands @reboot and the other shortcuts.
Why an @reboot job does not run
- Commands not found. Cron starts jobs with a tiny environment, typically
PATH=/usr/bin:/bin, no profile and no aliases. Use absolute paths (/usr/local/bin/node) or setPATH=at the top of the crontab. - Too early. At boot the network, disks, Docker or a database may not be ready yet. Add a pause such as
@reboot sleep 60 && /home/me/bin/start.sh, or better, make the script retry until what it needs is available. - It ran, but you cannot see it. Without a redirect, output goes to local mail, which most machines never deliver. Check the log above, or
grep CRON /var/log/syslog(Debian, Ubuntu) andjournalctl -u cronor-u crond. - Wrong crontab. Your user’s crontab runs as you;
sudo crontab -eedits root’s. Files in/etc/cron.d/and/etc/crontabneed an extra user field:@reboot root /path/script. - No cron at all. Minimal containers and some cloud images do not run a cron daemon, and in a container “boot” means the container starting, which is better handled by its own start command.
Some cron versions also run @reboot jobs if the cron service itself is restarted, while others keep a marker file so they run only once per boot. Do not rely on either behaviour.
The systemd alternative
On most Linux servers, a small service gives you ordering, restarts and logs for free:
# /etc/systemd/system/start-thing.service
[Unit]
Description=Start my thing
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/home/me/bin/start.sh
User=me
Restart=on-failure
[Install]
WantedBy=multi-user.target
Then sudo systemctl enable --now start-thing, and read its output with journalctl -u start-thing. Use cron @reboot for quick personal jobs; use a service for anything that should stay running.
The other shortcuts
| Shortcut | Same as | Runs |
|---|---|---|
@reboot | (no equivalent) | Once at startup |
@yearly, @annually | 0 0 1 1 * | Midnight on 1 January |
@monthly | 0 0 1 * * | Midnight on the 1st |
@weekly | 0 0 * * 0 | Midnight between Saturday and Sunday |
@daily, @midnight | 0 0 * * * | Every midnight |
@hourly | 0 * * * * | On the hour |
“Midnight” is in the server’s time zone, which on cloud servers is often UTC. The cron every 5 minutes guide covers time zones and step values.
Scheduled job never runs? See Cron job not running. Plain-English next runs: cron explainer · Anvil API.
Questions
Does @reboot run as root?
Only from root's crontab or a system file that names root. In your own crontab it runs as you.
Why does my @reboot script work by hand but not at boot?
Usually the minimal PATH or something not being ready yet, such as the network. Use full paths, add a short sleep or retry, and redirect output to a log to see the error.
Does @reboot run when cron restarts?
It depends on the cron version. Some run @reboot jobs whenever the daemon starts, others only once per boot. Write the script so running it twice is harmless.
Is @reboot supported everywhere?
It is supported by the common Linux crons (cronie, Vixie cron, Debian cron) but it is a non-standard extension, so very small cron implementations may lack it.
Published .