Working with Linux and Unix-based systems means eventually encountering cron jobs. Despite their widespread use, automated scheduling remains a stumbling block for many developers. This guide walks through cron fundamentals, scheduling syntax, and the mistakes that commonly derail otherwise well-planned automation.
Cron jobs are Linux utilities that execute programs or scripts according to a defined schedule. They're essential for automating recurring operations—anything from database backups to periodic data synchronization.
The mechanism is straightforward: you add entries to a scheduling table called crontab, specifying when and what to run. A background daemon (crond) continuously monitors this table and launches tasks at their designated times.
Note: A daemon is a background process that operates without user interaction—no input accepted, no output displayed. This terminology is specific to Unix/Linux environments.
Before diving in, confirm that cron is active on your system:
$ ps aux | grep cron
A running process like /usr/sbin/cron -f
indicates everything's operational. No output means you need to install it.
On Ubuntu:
$ sudo apt update && sudo apt install cron
After installation, enable the service:
$ sudo systemctl enable cron
A crontab entry follows this structure:
* * * * * /path/to/command.sh
| | | | |
| | | | └─── Weekday (0-6, 0 = Sunday)
| | | └──────── Month (1-12)
| | └───────────── Day of month (1-31)
| └────────────────── Hour (0-23)
└─────────────────────── Minute (0-59)
The asterisk * matches any value. Therefore * * * * * executes every single minute.
Running a task four times daily on weekdays:
0 */6 * * Mon-Fri /home/user/maintenance.sh
This executes at midnight, 6 AM, noon, and 6 PM, Monday through Friday.
The / operator sets intervals, while - defines ranges. For testing your expressions, crontab.guru provides instant plain-English translations of cron syntax.
The cron daemon checks for jobs every minute in these locations:
/etc/crontab
— system-level file with predefined directory shortcuts/var/spool/cron/crontabs/$USER
— individual user configurationsTo edit your personal crontab:
$ crontab -e
First-time users will be prompted to select an editor. Nano is recommended for beginners due to its simple interface.
Once selected, you'll see an empty file ready for your cron entries.
Swapping minute and hour fields is surprisingly easy. Always validate expressions through crontab.guru before adding them to your system.
Scripts that run perfectly from the command line may fail under cron. The culprit is usually environment variables. Cron doesn't load .bashrc
or .bash_profile
, leaving even common variables like $USER undefined
. Solutions include hardcoding values or explicitly sourcing configuration files within your script.
New shell scripts lack execution rights by default:
$ touch script.sh
$ ls -als script.sh
-rw-rw-r-- 1 user users 0 May 21 13:26 script.sh
Grant execution permissions:
$ chmod +x script.sh
$ ls -als script.sh
-rwxrwxr-x 1 user users 0 May 21 13:26 script.sh
Even bulletproof scripts fail when disk space or memory runs out. The only defense is proactive server monitoring.
Consider a job scheduled every minute that typically completes in seconds. If something delays execution beyond one minute, cron spawns a second instance. Then a third. Soon dozens of copies consume all available resources. Implement lock files to prevent concurrent execution.
Scripts relying on external APIs are vulnerable to undocumented changes on the provider's end, potentially breaking functionality without warning.
Cron maintains basic logs:
/var/log/syslog
/var/log/cron
Typical log entries look like:
Mar 29 16:00:01 mywebserver CRON[12624]: (user) CMD (/home/user/script.sh)
You can build logging into your scripts: writing events to files, capturing exit codes, redirecting stderr. This adds complexity and requires anticipating numerous failure scenarios.
Specialized tools offer a better approach. Cronitor is a monitoring platform for cron jobs, workers, and scheduled processes. The CronitorCLI utility automatically discovers and registers all your jobs, providing a centralized dashboard.
Access your Cronitor account settings and copy the key with CONFIGURE MONITORS permissions enabled.
Install the utility in /usr/bin
for system-wide access:
$ curl -sOL https://cronitor.io/dl/linux_amd64.tar.gz
$ sudo tar xvf linux_amd64.tar.gz -C /usr/bin/
$ sudo cronitor configure --api-key <your_key>
Replace <your_key
> with your actual API key. You'll see configuration confirmation including your hostname, timezone, and API key.
Run automatic discovery:
$ sudo cronitor discover
This scans all crontab files and prompts you to add discovered jobs. You'll assign each a descriptive name for dashboard identification.
For user-level jobs only, sudo isn't necessary. System-level monitoring requires elevated privileges.
After the first execution, your Cronitor dashboard displays comprehensive metrics:
Click "Edit" on any job card to access settings:
Configure alerts after five missed executions or two consecutive failures, depending on job criticality.
Daily Backup at Midnight
0 0 * * * /usr/local/bin/backup.sh
Temporary File Cleanup Every 6 Hours
0 */6 * * * find /tmp -type f -mtime +7 -delete
Monthly Report on First Day
0 9 1 * * /home/user/send_monthly_report.sh
Update Checks Every 15 Minutes During Business Hours
*/15 9-17 * * Mon-Fri /usr/bin/check_updates.sh
Cron remains a powerful automation tool in Linux environments despite its potential complexities. Understanding scheduling syntax, recognizing common errors, and implementing monitoring systems prevent most issues. Services like Cronitor dramatically simplify job tracking, alerting you to failures before they impact operations.
Properly configured cron with reliable monitoring forms the backbone of automated task management in any production environment.