cron runs jobs at exact times. If the machine is off (or rebooting) at that moment, the job simply doesn’t run. anacron solves this for periodic jobs: it remembers when each job last ran, and if a day, week or month has passed, it runs the job after the system comes back. It’s mainly used for the system’s daily, weekly and monthly maintenance jobs.

cron vs anacron

cron anacron
Schedule precision Exact minute Daily, weekly, monthly (or every N days)
Missed runs Skipped Run later, after a delay
Runs as Any user root (system jobs)
Typical use Servers that are always on, precise timing Laptops, desktops, servers that may be off; system maintenance

On most Debian and Ubuntu systems, both are present: cron triggers anacron, which runs /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly.

How it works on Debian/Ubuntu

cat /etc/anacrontab
ls /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
ls /var/spool/anacron/        # timestamps of the last runs

/etc/anacrontab:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

# period  delay  job-identifier  command
1         5      cron.daily      run-parts --report /etc/cron.daily
7         10     cron.weekly     run-parts --report /etc/cron.weekly
@monthly  15     cron.monthly    run-parts --report /etc/cron.monthly
Field Meaning
period Days between runs (1, 7), or @daily, @weekly, @monthly
delay Minutes to wait after anacron starts, so jobs don’t all run at boot
job-identifier Name used for the timestamp file in /var/spool/anacron/
command What to run

START_HOURS_RANGE=3-22 limits when jobs may start, and RANDOM_DELAY=45 adds up to 45 random minutes (RHEL-family defaults include these).

Add your own job

Easiest: drop an executable script into one of the directories:

sudo install -m 755 /dev/stdin /etc/cron.daily/backup-config <<'EOF'
#!/bin/sh
tar czf /var/backups/etc-$(date +%F).tgz /etc 2>/dev/null
find /var/backups -name 'etc-*.tgz' -mtime +14 -delete
EOF

run-parts only runs files whose names contain letters, digits, underscores and hyphens: no dots (so backup.sh is silently skipped). Test which scripts would run:

run-parts --test /etc/cron.daily

Or add a line to /etc/anacrontab:

3   20   cleanup-uploads   /usr/local/bin/cleanup-uploads.sh

(Runs every 3 days, 20 minutes after anacron starts.)

Test and force runs

sudo anacron -T                  # check anacrontab syntax
sudo anacron -f -n -d            # force all jobs now, no delay, in the foreground
sudo anacron -f -n -d cron.daily # just one job

Timestamps are updated after each run. Delete a timestamp file to make a job due again.

On always-on servers

On a VPS that runs 24/7, missed runs only happen during reboots and maintenance, so plain cron is usually fine. anacron still matters for the system’s own maintenance scripts (log rotation, apt cleanups, man-db), which is why it’s installed by default.

For your own scheduled tasks, systemd timers with Persistent=true provide the same catch-up behaviour, plus better logging and dependencies. See systemd timers.

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=30m

Troubleshooting

  • A script in cron.daily never runs: check its name (no dots), that it’s executable, and run-parts --test.
  • Jobs run at odd times: the delay and random delay settings, or START_HOURS_RANGE, shift them. That’s intended.
  • Nothing runs at all: on systemd systems, anacron may be started by a timer (systemctl list-timers | grep anacron) rather than by cron. Check that it’s enabled.

Quick reference

Task Command / file
Config /etc/anacrontab
Daily/weekly/monthly scripts /etc/cron.{daily,weekly,monthly}/
Last runs /var/spool/anacron/
Which scripts run run-parts --test /etc/cron.daily
Force now sudo anacron -f -n -d

Related: crontab guide and cron job not running.

  • Linux
  • Cron
  • Automation