Cron

On this page 7

Cron is the Unix and Linux time-based job scheduler: a background daemon that wakes up every minute, reads schedule tables called crontabs and starts the commands whose time specification matches the current minute. In Linux process management, cron is the classic way to run recurring, unattended processes such as backups, log rotation, report generation and cleanup tasks.

Each scheduled command runs as a new process owned by the crontab’s user, with its own minimal environment and no terminal. Understanding that execution context explains most of the problems people meet when a script works in a shell but fails when cron starts it.

How the cron daemon schedules jobs

The cron daemon, called crond or cron depending on the distribution, starts at boot and checks its tables once per minute. Common implementations are cronie on Fedora and RHEL-family systems and Vixie cron derivatives on Debian and Ubuntu. The minute is the smallest scheduling unit; cron cannot start jobs at second-level precision.

When an entry matches, the daemon forks a child process, switches to the owner’s user and group, sets a few environment variables and runs the command through /bin/sh. Standard output and error are collected and, by default, mailed to the owner if a local mail system is configured; otherwise the output is discarded or logged, depending on the implementation.

Cron reads tables from several places, which the table below lists.

LocationOwnerFormat
User crontabs edited with crontab -eIndividual usersFive time fields and a command
/etc/crontabSystem administratorFive time fields, a user name, a command
/etc/cron.d/Packages and administratorsSame as /etc/crontab
/etc/cron.hourly, daily, weekly, monthlyPackagesExecutable scripts, no time fields
Where cron schedules are stored

The crontab time format

A crontab entry consists of five time and date fields followed by the command. A job runs when the minute, hour and month fields match and either the day-of-month or the day-of-week field matches, if both are restricted.

FieldAllowed valuesExample
Minute0 to 5930
Hour0 to 232
Day of month1 to 311
Month1 to 12 or names*
Day of week0 to 7 or names, 0 and 7 mean Sunday1-5
Fields of a crontab entry

Fields accept lists, ranges and steps: 1,15 means both values, 1-5 a range and */15 every fifteenth unit. Most implementations also understand shortcuts such as @daily, @hourly and @reboot. The table shows frequent patterns.

ExpressionMeaning
*/5 * * * *Every five minutes
0 * * * *At the start of every hour
30 2 * * *Daily at 02:30
0 9 * * 1-5At 09:00 on weekdays
0 0 1 * *At midnight on the first day of each month
@rebootOnce after the daemon starts
Common schedule expressions

Cron compared with other schedulers

Cron is the most widespread scheduler but not the only one. Its closest alternatives differ in how they handle missed runs, dependencies and logging.

ToolSchedule typeMissed runsStrengths
cronRecurring, minute resolutionSkipped while the system is offSimple, universal, portable
anacronDaily, weekly, monthlyRun after the system startsLaptops and machines that power off
systemd timersCalendar or monotonicOptional catch-up with Persistent=trueJournal logging, dependencies, resource limits
atOne-timeNot applicableSingle deferred commands
Kubernetes CronJobCron syntax in a clusterConfigurable deadlineContainerized jobs on cluster nodes
Cron and related scheduling tools

Systemd timers start jobs as service units, so they can use cgroup resource limits, nice values and CPU affinity set in the unit, and their output lands in the journal. Cron remains preferable where portability across Unix systems and a single readable line per job matter more.

Execution environment and practical configuration

Cron jobs run with a deliberately small environment: typically HOME, LOGNAME, SHELL=/bin/sh and a short PATH such as /usr/bin:/bin. Shell startup files are not read, and no terminal is attached, so interactive prompts hang or fail.

  • Use absolute paths for commands and files, or set PATH at the top of the crontab.
  • Redirect output to a log file, for example >> /var/log/job.log 2>&1, so failures leave evidence.
  • Set MAILTO to receive output by mail, or to an empty value to suppress mail.
  • Prevent overlapping runs with flock -n when a job may take longer than its interval.
  • Lower priority of heavy jobs with nice and ionice to protect interactive workloads.

Access can be restricted with cron.allow and cron.deny files. Production teams also keep crontabs in version control or configuration management, because a schedule edited only on one server is easily lost or forgotten.

Common pitfalls

Most cron failures are silent, which makes their causes worth knowing in advance.

  • Percent signs: an unescaped % in a crontab command is turned into a newline; write \%, for example in date formats.
  • Time zone and daylight saving: jobs between 01:00 and 03:00 may run twice or not at all on transition days in many zones.
  • Day-of-month and day-of-week together: restricting both means either condition triggers the job, not both.
  • Missing final newline: some implementations ignore the last line of a crontab without a newline.
  • Synchronized load: thousands of machines running jobs at minute 0 cause load spikes; a random delay spreads them.

When a job seems not to run, the fastest diagnosis is to check the daemon log first, through the journal or the system log, which records each start. If the job started, the next step is to reproduce its environment with env -i and a short PATH, which usually reveals the missing variable or relative path within minutes.

Explained without jargon

Many computer chores need to happen regularly: saving backups at night, cleaning up old files each week or sending a report every Monday morning. Doing this by hand is tedious and easy to forget.

Cron is an alarm clock for the computer. A person writes a short line saying when a task should run and what it is, and cron starts it at exactly that time, every time. Once a task is scheduled, it runs without anyone being present.

A typical use case

An administrator of a small company’s Linux server needs a nightly database backup that finishes before staff arrive. She writes a backup script and adds the line 30 2 * * * flock -n /run/backup.lock /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 to the root crontab.

The first night, the log shows that the pg_dump command was not found, because cron’s short PATH did not include its directory. After she sets PATH at the top of the crontab, the backup runs every night at 02:30, the lock prevents overlapping runs when a backup is slow, and the log records every result.

A weekly check of the log file and an alert on missing entries complete the setup, so a failed backup is noticed within a day instead of when a restore is needed.