reliably catching up on missed cron jobs
A classic cron job scheduled to run at 03:00 gets simply skipped on a powered off laptop, without any notification. Anacron solves exactly this problem by checking, at the next power on, which jobs were due and automatically running them. This article shows how anacron works, how to configure /etc/anacrontab, and how to sensibly combine it with classic cron.
Table of Contents
- 1. The core problem: cron and systems that are not always on
- 2. How anacron detects and catches up missed jobs
- 3. Configuring /etc/anacrontab in detail
- 4. Creating your own anacron jobs
- 5. Combining anacron and cron sensibly
- 6. The systemd alternative: persistent timers as a replacement
- 7. Debugging anacron runs and checking logs
- 8. Typical pitfalls in desktop and laptop operation
- 9. anacron, cron, and systemd timers compared
- 10. Summary
- 11. FAQ
1. The core problem: cron and systems that are not always on
Classic cron assumes something that holds true on servers but is regularly violated on laptops and desktops: the system runs around the clock. If a machine is powered off or suspended at a job's scheduled execution time, the job simply gets skipped, with no error message, no log entry, no notification at all. A daily backup job scheduled to run at 02:00 will effectively never execute on a laptop that gets turned off every night.
Anacron was built for exactly this scenario and complements cron rather than replacing it. Instead of tying jobs to fixed times, anacron works with intervals measured in days and checks, on every start, whether enough time has passed since the last successful run. If so, the job is caught up, regardless of how long the machine was previously powered off. This mindset makes anacron the ideal tool for anything that needs to run reliably at regular intervals without needing minute level precision.
2. How anacron detects and catches up missed jobs
The core principle of anacron is based on timestamp files in the /var/spool/anacron/ directory. For every configured job, a file exists there that stores the date of the last successful run as a plain string. On startup, anacron compares this date against the configured interval in days and the current date. If the difference is equal to or greater than the interval, the job is considered due and gets executed.
After a successful run, anacron automatically updates the timestamp file to the current date. Important to understand: anacron itself does not run permanently in the background like a daemon, but is typically triggered once a day via a cron entry or a systemd unit, usually shortly after booting. If a laptop starts up at nine in the morning, the next anacron run immediately checks whether daily or weekly due jobs need to be caught up, and executes them after a configurable delay so the startup is not immediately burdened.
3. Configuring /etc/anacrontab in detail
The central configuration file /etc/anacrontab follows its own format, different from cron, with four columns: interval in days, delay in minutes after start, a unique job identifier, and the command to execute. The job identifier also serves as the filename for the timestamp file under /var/spool/anacron/ and must therefore be unique within the file.
On most distributions, a default configuration already exists that runs the directories /etc/cron.daily/, /etc/cron.weekly/, and /etc/cron.monthly/ through anacron instead of directly through cron. This explains why many distributions reliably run these three default directories even when a system is regularly powered off at night, while individual crontab entries without an anacron connection actually get missed.
# /etc/anacrontab
# period delay job-identifier command
# Run daily jobs, 5 minutes after anacron starts
1 5 cron.daily run-parts --report /etc/cron.daily
# Run weekly jobs, 10 minutes after anacron starts
7 10 cron.weekly run-parts --report /etc/cron.weekly
# Run monthly jobs, 15 minutes after anacron starts
@monthly 15 cron.monthly run-parts --report /etc/cron.monthly
# Custom job: check disk space every 3 days
3 20 disk-check /usr/local/bin/disk-space-check.sh
4. Creating your own anacron jobs
For custom scripts there are two common approaches: either place a script directly into one of the default directories /etc/cron.daily/, /etc/cron.weekly/, or /etc/cron.monthly/, or add a dedicated entry directly to /etc/anacrontab. The first approach is more pragmatic for standard intervals, because the distribution already handles the connection to anacron and no manual configuration of the timestamp logic is needed.
Scripts in these directories must be executable and must not carry a file extension, since run-parts ignores files with dots in their name by default, to prevent accidental execution of backup files like script.sh.bak. For intervals that differ from daily, weekly, or monthly, for example every three days, a dedicated entry directly in /etc/anacrontab is the right choice, with a unique job identifier and its own delay that does not collide with the default jobs.
# Create a custom daily script
sudo tee /etc/cron.daily/backup-check <<'EOF'
#!/bin/bash
set -euo pipefail
/usr/local/bin/verify-backup-integrity.sh >> /var/log/backup-check.log 2>&1
EOF
# Make it executable and ensure no file extension
sudo chmod +x /etc/cron.daily/backup-check
# Check which anacron timestamp files already exist
ls -la /var/spool/anacron/
# Manually trigger anacron for testing (respects delays)
sudo anacron -f -n -t /etc/anacrontab
5. Combining anacron and cron sensibly
The sensible split between anacron and classic cron follows a simple rule of thumb: anything that must run at an exact time to the minute, for example an hourly data sync, belongs in cron. Anything that only needs to run regularly within a day, a week, or a month, without the exact time mattering, for example a weekly log cleanup, belongs in anacron. Both systems run in parallel and do not interfere with each other as long as they cover different tasks.
A common misunderstanding: anacron does not fully replace cron, it specifically complements it for cases where reliability matters more than precision. On a server that runs permanently anyway, anacron brings barely any advantage over classic cron, which is why it is mostly only used there for the default directories cron.daily and cron.weekly. On laptops and desktops, however, the combination of both systems is the most robust solution to guarantee both precise timing and guaranteed catch up.
6. The systemd alternative: persistent timers as a replacement
Anyone who has already fully switched to systemd timers can achieve similar catch up functionality without anacron by setting the Persistent=true option in the timer unit. This makes systemd remember when a timer last fired, and runs it immediately after the next boot if the scheduled time was missed during a powered off phase. The behavior is conceptually very similar to anacron, but more deeply integrated into systemd and uniformly visible alongside other timers via systemctl list-timers.
The practical difference lies in the configuration syntax and granularity: systemd timers with OnCalendar allow far more flexible time expressions than anacron's simple day interval, while anacron with its simple text file remains quicker to grasp for many administrators. For new desktop installations that rely fully on systemd anyway, Persistent=true is often the more modern choice, while existing systems with established cron.daily scripts can usually stay with anacron without issues.
7. Debugging anacron runs and checking logs
When jobs fail to run, the first step is to check the timestamp files under /var/spool/anacron/. A date much older than expected indicates that anacron itself is not being triggered regularly, for example because the underlying cron entry or systemd unit for the anacron invocation itself is missing or disabled. The command anacron -f -n -t /etc/anacrontab forces an immediate test run of all configured jobs, regardless of the last execution date, which is indispensable for troubleshooting.
For more detailed diagnosis, it is worth checking /var/log/syslog or journalctl -u anacron, where anacron logs which jobs it recognized as due and executed. The -d option additionally keeps anacron in the foreground and writes all debug output directly to the console, which is especially helpful when a script inside a cron.daily directory does run but its result does not appear as expected.
# Inspect timestamp files to see when jobs last ran
cat /var/spool/anacron/cron.daily
cat /var/spool/anacron/cron.weekly
# Check the system log for anacron activity
journalctl -u anacron --since "3 days ago"
# Force a full debug run in the foreground
sudo anacron -d -f -n -t /etc/anacrontab
# Verify run-parts correctly skips backup files
run-parts --list /etc/cron.daily
8. Typical pitfalls in desktop and laptop operation
A common mistake is assuming anacron reacts to suspend to RAM the same way it reacts to a full shutdown. On a laptop that only gets put to sleep and never fully restarted, anacron may not run again at all, because the underlying trigger, usually a daily systemd timer or a cron entry, is itself affected by suspend. For such setups, a systemd-timer with WakeSystem=true should also be considered, to specifically wake the system from suspend.
A second pitfall involves scripts that assume an existing network connection. If a daily backup job gets triggered by anacron right after system startup, before a Wi-Fi connection is actually established, the upload to a remote storage target fails without anacron itself reporting an error, because anacron only logs execution, not its content level success. A robust script should therefore check itself whether the required network connection exists, and return a clear exit code on failure, one that shows up in the log via run-parts --report.
9. anacron, cron, and systemd timers compared
The choice between the three scheduling mechanisms depends on how critical exact timing is versus guaranteed catch up.
| Criterion | cron | anacron | systemd timer (persistent) |
|---|---|---|---|
| Exact timing | Yes, minute precise | No, only day intervals | Yes, with OnCalendar |
| Catching up missed jobs | No | Yes, at next start | Yes, with Persistent=true |
| Configuration format | crontab syntax | Simple text file | Unit files (.timer) |
| Ideal for | Servers, fixed times | Laptops, desktops | Modern systemd systems |
| Waking from suspend | No | No | Yes, with WakeSystem |
In practice, the three approaches do not exclude each other but complement one another: cron for time critical tasks, anacron or persistent timers for anything that needs to run regularly but not to the exact minute, and explicit waking from suspend only where it is truly required.
Mironsoft
Scheduling concepts and automation for Linux servers and workstations
Want missed jobs caught up reliably?
We set up robust scheduling strategies with anacron, cron, and systemd timers, so important maintenance tasks run reliably even on systems that are not always on.
anacron setup
anacrontab configuration matched to your hardware and usage patterns
Migration to systemd timers
Switching to persistent timers for modern systemd environments
Script hardening
Network checks and exit codes for robust catch up jobs
10. Summary
Anacron solves a problem that classic cron structurally cannot solve on systems that are not always on: missed jobs are not silently skipped, they get automatically caught up at the next start. Configuration through /etc/anacrontab with an interval in days, a delay, and a unique job identifier is simple but sufficient for most maintenance tasks on laptops and desktops. The default directories cron.daily, cron.weekly, and cron.monthly already run through anacron on most distributions.
For modern systemd based systems, Persistent=true in timer units offers comparable catch up functionality with more flexible time expressions via OnCalendar. The most robust strategy combines cron for time critical tasks with anacron or persistent timers for anything that needs to run regularly but not to the exact minute, complemented by network aware scripts that work correctly even after a delayed start.
Anacron for laptops and desktops, the key points at a glance
Core principle
Timestamp files under /var/spool/anacron/ compare the last run against the configured interval in days.
Configuration
/etc/anacrontab with interval, delay, unique identifier, and command, usually via run-parts.
Combining with cron
cron for exact timing, anacron for anything where catching up matters more than the exact time.
systemd alternative
Persistent=true in timer units offers similar catch up logic with more flexible OnCalendar syntax.