cron
Cron schedules commands to run at regular times. Five time fields + the command. crontab -e for per-user; /etc/cron.d/* for system. Modern Linux uses systemd timers for richer scheduling.
Schedule format + systemd timers
EXAMPLE
# 1) crontab format
# minute hour day-of-month month day-of-week command
# 0-59 0-23 1-31 1-12 0-7 (0,7 = Sunday)
#
# Every 5 min: */5 * * * *
# Top of every hour: 0 * * * *
# Daily at 02:30: 30 2 * * *
# Mondays at 09:00: 0 9 * * 1
# 1st of month, 04:00: 0 4 1 * *
# Every 15 min, business hours: */15 9-17 * * 1-5
# 2) Common shortcuts (some implementations)
# @reboot — run once at boot
# @yearly — Jan 1 00:00
# @monthly — 1st 00:00
# @weekly — Sunday 00:00
# @daily — 00:00
# @hourly — top of hour
# 3) Edit your user crontab
crontab -e # opens $EDITOR
crontab -l # list
crontab -r # remove ALL (careful!)
crontab -u www-data -l # another user's (as root)
# Example user crontab:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=ops@example.com
SHELL=/bin/bash
# Backup database every day at 02:00
0 2 * * * /opt/myapp/bin/backup.sh > /var/log/backup.log 2>&1
# Weekly cleanup
0 3 * * 0 find /tmp -type f -mtime +7 -delete
# Every minute health check
* * * * * /opt/myapp/bin/healthcheck.sh
# 4) Important — capture output
# * * * * * /path/to/cmd # output emailed to MAILTO if set
# * * * * * /path/to/cmd > /var/log/cmd.log 2>&1 # redirect
# * * * * * /path/to/cmd > /dev/null 2>&1 # silence (lose errors!)
# 5) Environment
# Cron jobs run with a MINIMAL environment — almost no PATH, no aliases.
# - Use absolute paths to binaries OR set PATH at the top of crontab
# - Source /etc/profile if you depend on bash login env:
# * * * * * . /etc/profile; /opt/myapp/bin/cmd
# 6) System cron — /etc/cron.d/<name>
# Same syntax PLUS a 'user' field after the time fields:
# 0 2 * * * www-data /opt/myapp/bin/backup.sh
# /etc/cron.{daily,hourly,weekly,monthly}/ — drop a script; runs with default schedule
# 7) Logging
# Most distros log cron activity to:
# /var/log/cron (RHEL/CentOS)
# /var/log/syslog (Debian/Ubuntu)
grep CRON /var/log/syslog | tail
# 8) Test before scheduling
# Run the EXACT command as the user, in /bin/sh, with empty env:
sudo -u www-data env -i /bin/sh -c '/opt/myapp/bin/backup.sh'
# 9) Locking — prevent overlapping runs
# Use flock to ensure only one instance runs at a time:
* * * * * /usr/bin/flock -n /tmp/myjob.lock /opt/myapp/bin/poll.sh
# 10) DST gotcha
# Jobs scheduled to run when the clock skips (e.g. 02:30 on DST-forward day) may NOT run.
# Use 'anacron' for jobs that must run even after sleep / power-off / clock changes.
# === systemd timers — modern alternative ===
# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup
[Service]
Type=oneshot
User=www-data
ExecStart=/opt/myapp/bin/backup.sh
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 02:30
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true # run on next boot if missed (DST / downtime safe)
RandomizedDelaySec=600 # avoid thundering herd
[Install]
WantedBy=timers.target
# Enable + start
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
sudo systemctl list-timers --all
# Run on demand
sudo systemctl start backup.service
# Logs (centralised, structured)
journalctl -u backup.service
journalctl -u backup.service --since today
# OnCalendar syntax cheat sheet
# *-*-* 02:30:00 daily at 02:30
# Mon *-*-* 09:00:00 Monday 09:00
# *-*-1 04:00:00 1st of month 04:00
# *-*-* *:00/15 every 15 min
# *-*-* 09..17:00 hourly between 09:00 and 17:00
# daily, weekly, monthly — shortcuts
# Why systemd timers > cron
# - Centralised logs (journalctl)
# - Persistent=true catches missed runs
# - RandomizedDelaySec avoids thundering herd
# - Job description in Unit metadata
# - Resource limits via the .service (CPUQuota, MemoryMax)
# - Dependency ordering with other units (After=postgresql.service)
# === When to use what ===
# Cron : portable POSIX systems, simple recurring tasks
# systemd timer : Linux production servers, audit + reliability matter
# Application schedule (Sidekiq cron, Celery beat, Airflow): when job logic is in your app stack
# Cloud scheduler (EventBridge, Cloud Scheduler): serverless
# === Useful tools ===
# crontab.guru — visual cron expression tester
# anacron — runs missed jobs on next boot (laptops/desktops)
# fcron — modern cron with richer scheduling
# at — one-off scheduled commands (`at 17:00 tomorrow`)
Why it matters
For new Linux servers, prefer systemd timers — you get journald logs, missed-run recovery, and randomised delays for free. Reach for cron when you need POSIX portability or simplicity.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…