Topic 7.3
Cron & Scheduled Tasks
In one line
cron runs a command on a recurring schedule with zero manual intervention — the standard way anything needs to happen 'every night at 2am' or 'every 5 minutes' on a Linux server.
Think of it like this
Setting a recurring alarm rather than remembering to do something manually every single day — cron is exactly that, but for commands on a server, running reliably in the background whether or not anyone is watching.
Key ideas
- 01
crontab -eopens your personal crontab (a per-user schedule file) in an editor.crontab -llists your current scheduled jobs. Each line follows the formatminute hour day month weekday command— five time fields, each accepting a specific number, a range, a list, or*(meaning 'every'), followed by the command to run. - 02
A genuinely useful pattern for remembering the field order: 'minute, hour, day (of month), month, day (of week)' —
0 2 * * *means 'at minute 0 of hour 2, every day, every month, every day of the week' — i.e., every night at 2:00 AM.*/15 * * * *means 'every 15 minutes' (the*/Nsyntax for 'every N units'). - 03
Cron jobs run with a MINIMAL environment — none of the environment variables, PATH entries, or shell configuration you're used to from an interactive login session are guaranteed to be present. This is precisely why a cron job that works perfectly when run manually can mysteriously fail when run BY cron — always use absolute paths (
/usr/bin/python3instead of justpython3) and explicitly set any environment variables the job actually needs. - 04
Cron jobs should always REDIRECT their output somewhere you can actually check (
command >> /var/log/myjob.log 2>&1), since by default cron either discards output entirely or emails it to a local mail system that often isn't even configured on a typical server — without explicit redirection, a silently failing cron job can go completely unnoticed indefinitely. - 05
/etc/cron.d/,/etc/cron.daily/,/etc/cron.hourly/are SYSTEM-WIDE cron locations for scripts that should run regardless of which user is logged in — genuinely useful for infrastructure-level scheduled tasks (likelogrotateitself, which typically runs from here) as distinct from a specific user's own personalcrontab -eschedule. - 06
SYSTEMD TIMERS are the modern alternative to cron on systemd-based distributions: a
backup.timerunit (OnCalendar=*-*-* 02:00:00,Persistent=trueto catch up on runs missed while the machine was off,RandomizedDelaySec=10mto spread load) triggers a matchingbackup.service. You get logs injournalctl -u backup.service, dependencies, resource limits, and a clear view of the schedule withsystemctl list-timers. Cron is still everywhere and fine for simple jobs; timers are better when you want logging and reliability built in.
In your stack
- →
A nightly Spring Boot batch job (a report generator, a data-cleanup task) is a classic cron use case:
0 2 * * * /usr/bin/java -jar /opt/myapp/batch.jar >> /var/log/myapp/batch.log 2>&1— note the absolute paths to bothjavaand the JAR, exactly the defensive habit this topic emphasizes for cron's minimal environment.
Code & diagrams
Real crontab entries — always use absolute paths and redirect output explicitly.
# Edit your personal crontab
crontab -e
# --- Example entries (each is one line in the crontab) ---
# Every night at 2:00 AM
0 2 * * * /usr/bin/java -jar /opt/myapp/batch.jar >> /var/log/myapp/batch.log 2>&1
# Every 15 minutes
*/15 * * * * /opt/myapp/venv/bin/python /opt/myapp/healthcheck.py >> /var/log/myapp/health.log 2>&1
# Every Sunday at 3:00 AM (day-of-week field: 0 = Sunday)
0 3 * * 0 /usr/bin/find /var/log/myapp -name "*.log" -mtime +30 -delete
# List your currently scheduled jobs
crontab -lExplain it without notes
Why does a script that runs perfectly when you type it manually sometimes fail silently when run by cron?
Why is explicitly redirecting a cron job's output to a log file considered essential rather than optional?
Practice
Write a crontab entry that would run a simple script every 5 minutes, using an absolute path and redirecting output to a log file, without actually installing it (unless you have a safe test environment).
Decode what 30 4 1 * * means in crontab syntax before checking your answer against this topic's field-order explanation.
Trade-offs
- ↔
Cron is dead simple and available on every Linux machine with zero setup, but it has no built-in retry logic, no alerting if a job fails, and no protection against two overlapping runs of the same slow job if it takes longer than its own interval — for anything genuinely critical, a real job scheduler or workflow tool (Airflow, or a managed cloud scheduler) provides these guarantees directly, while cron remains the right choice for simple, low-stakes recurring tasks.
Done when you can
I can write a crontab entry with the correct minute/hour/day/month/weekday field order.
I know cron jobs need absolute paths since they run in a minimal environment.
I always redirect a cron job's output to a log file rather than letting it disappear silently.