What Cron Is and Why Server Administrators Rely on It
If you manage a Linux server, you will eventually need certain tasks to run automatically without manual intervention. Database backups at 3am, weekly log rotation, hourly data synchronisation, or monthly report generation all need consistent execution regardless of whether you are at your desk. Manually running these tasks is error-prone, inconsistent, and simply impractical when servers need to operate around the clock.
Cron provides a solution by allowing you to define scheduled tasks that run automatically at specified times. It is a time-based job scheduler built into Unix and Linux systems, and it has been a cornerstone of server administration for decades. Understanding how to use cron effectively is a fundamental skill for anyone responsible for maintaining Linux servers, whether you run a single VPS or manage multiple production environments.
Automated tasks that run on a schedule are inherently more reliable than manual processes. A manual backup run during a busy period often gets skipped, and an administrator on holiday cannot execute urgent maintenance. A backup script scheduled for 3am every morning runs regardless of these circumstances, providing consistency that manual processes cannot match.
How Cron Works: The Cron Daemon in Detail
Cron operates as a background daemon, typically called cron or crond. This daemon runs continuously on the system, checking for scheduled jobs at one-minute intervals. When the current time matches a job's time specification, cron executes the associated command or script.
The daemon starts automatically on most Linux distributions through the system service manager. You can verify that cron is running with the following command:
systemctl status cron
If cron is not running for any reason, you can start and enable it with these commands:
sudo systemctl start cron
sudo systemctl enable cron
The enable command ensures cron starts automatically after a server reboot, which is important for production environments where unattended restarts may occur.
The Crontab Format: Defining Scheduled Tasks
Cron tasks are stored in a crontab file, which stands for "cron table". Each user on a Linux system can have their own crontab file containing personal scheduled tasks. The system also maintains a set of scheduled tasks in /etc/cron.d/ and standard directories like /etc/cron.daily/, /etc/cron.hourly/, /etc/cron.weekly/, and /etc/cron.monthly/.
To edit your own crontab file, run:
crontab -e
This command opens your crontab file in your default text editor. The first time you run this command, you may be prompted to select an editor. Most users prefer nano for its simplicity, though vim is available if you are comfortable with it.
Each line in a crontab follows this standard format:
* * * * * /path/to/command
The line consists of five time fields followed by the command to execute. The five stars represent, in order: minute, hour, day of month, month, and day of week.
Cron Schedule Syntax Explained
The cron schedule syntax can appear confusing initially, but it follows a logical pattern once you understand each field and the available operators.
Field Values and Operators
Understanding the basic building blocks makes cron syntax straightforward to read and write:
- Specific value:
30means "at minute 30" or "on the 30th day" - Asterisk:
*means "every" possible value for that field - Range:
1-5means "every value from 1 through 5" - Step value:
*/15means "every 15 units" - List:
1,3,5means "at values 1, 3, and 5"
Common Schedule Examples
* * * * * Every minute
30 * * * * Every hour, at minute 30
0 * * * * Every hour, at minute 0 (the start of each hour)
0 0 * * * Every day at midnight
30 2 * * * Every day at 02:30
0 3 * * 1 Every Monday at 03:00
0 0 1 * * First day of every month at midnight
0 0 * * 0 Every Sunday at midnight
*/15 * * * * Every 15 minutes
0 */2 * * * Every 2 hours
30 4 * * 1-5 Weekdays at 04:30
0 0 * * 1,3,5 Monday, Wednesday, and Friday at midnight
The day-of-week field treats 0 and 7 as Sunday, with 1 through 6 representing Monday through Saturday respectively.
If you are building automation scripts as part of your bash scripting workflow, scheduling those scripts with cron is a natural next step for recurring automation tasks on your server.
Scheduling Common Server Administration Tasks
Here are practical examples of scheduling tasks you are likely to encounter when managing a Linux server.
Daily Database Backup
Run a backup script every day at 3am:
0 3 * * * /usr/local/bin/backup.sh
Weekly Log Rotation
Rotate logs every Sunday at 2am:
0 2 * * 0 /usr/local/bin/rotate-logs.sh
PHP Script Execution
Run a PHP script every 15 minutes:
*/15 * * * * /usr/bin/php /var/www/html/yourdomain.co.uk/cron.php
Clearing Temporary Files
Remove temporary files every day at 5am to free up disk space:
0 5 * * * /usr/local/bin/cleanup-temp.sh
Environment Variables and PATH Considerations
Cron does not load your interactive shell environment. This is one of the most common reasons scripts work when run manually but fail under cron. Variables like PATH, HOME, and any custom environment settings may not be available or may have different values than you expect.
Always use absolute paths in cron commands to avoid PATH resolution issues. Instead of relying on system PATH lookups, specify the full path to commands and scripts. Alternatively, you can set the PATH variable at the top of your crontab:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 3 * * * /usr/local/bin/backup.sh
When developing scripts that will run under cron, test them in a simulated cron environment first. The env -i command clears all environment variables, giving you a clean slate similar to what cron provides:
env -i HOME=$HOME PATH=$PATH /usr/local/bin/myscript.sh
If your script works in your normal shell session but fails with this command, it likely depends on environment variables that are not available in the cron environment. Update the script to explicitly set required variables or use absolute paths throughout the script.
Managing Command Output and Logging
By default, cron sends any output from commands to the local mail system. If a cron job produces output you want to review for debugging purposes, it is delivered as local system mail. Check your local mail with:
mail
For most server administration tasks, you will want to redirect output to a log file instead. This approach makes it easier to review historical output and monitor job execution over time:
0 3 * * * /usr/local/bin/backup.sh >> /var/log/cron-backup.log 2>&1
The >> operator appends standard output to the log file rather than overwriting it. The 2>&1 construction redirects standard error to the same destination as standard output, so both normal output and error messages go into the same log file. Without this redirection, cron sends any output to the local mail spool, where it may accumulate unread and cause disk space issues over time.
Disabling Email Notifications
If a cron job does not produce meaningful output, or if you are already logging everything to a file, you can suppress email notifications entirely:
0 3 * * * /usr/local/bin/backup.sh > /dev/null 2>&1
Alternatively, set the MAILTO variable at the top of your crontab:
MAILTO=""
0 3 * * * /usr/local/bin/backup.sh
An empty MAILTO value disables email notification for all cron jobs in that particular crontab file.
System Cron Directories and Run-Parts
On Ubuntu, Debian, and many other Linux distributions, scripts in the system cron directories run automatically at scheduled intervals without requiring any crontab configuration:
/etc/cron.hourly/ runs every hour
/etc/cron.daily/ runs every day
/etc/cron.weekly/ runs once per week
/etc/cron.monthly/ runs once per month
Scripts placed in these directories are executed by the run-parts command, which runs executable files found in the directory. To use this approach, place your script in the appropriate directory, ensure it is executable with chmod +x, and include a proper shebang line at the top such as #!/bin/bash or #!/bin/sh.
The anacron package, installed by default on Ubuntu desktop installations and common on many server setups, ensures that cron.daily tasks run even if the server was powered off at the scheduled time. When the server starts up after a missed daily run, anacron executes the task. On servers that run continuously without downtime, this behaviour is less relevant, but anacron still provides useful consistency guarantees for environments where occasional restarts occur.
Common Cron Mistakes That Cause Silent Failures
One of the most frustrating aspects of cron is that failed jobs often fail silently. Unlike a task run manually in your terminal, a failed cron job does not display errors on your screen. Understanding common mistakes helps you avoid them and troubleshoot effectively when issues arise.
Environment Differences
The most common cron problem is environment differences. A script that works perfectly when run manually but fails under cron is almost always due to a missing environment variable, a different working directory, or missing PATH entries. Always test scripts with a simulated cron environment before relying on them in production.
Relative Paths in Scripts
Another common mistake is using relative paths for input or output files. If your script references data/input.csv, it will fail under cron unless the script changes to the correct directory first or uses an absolute path throughout. This issue often surfaces as a file not found error in your cron logs.
Missing Shebang Line
Scripts placed in system cron directories must have a proper shebang line as the first line. Without it, the system does not know which interpreter to use to run the script. Always include #!/bin/bash or #!/usr/bin/env bash at the top of shell scripts.
Permissions Issues
The script file must be executable. Use chmod +x /path/to/script.sh to add execute permissions. Additionally, the user whose crontab the job runs in must have read access to the script and execute permissions on it. Permissions problems often manifest as silent failures where the cron log shows the job was triggered but no output or results appear.
Verifying Cron Job Execution
When troubleshooting cron issues, checking several places helps you understand what happened and why.
Checking System Logs
Cron logs its activity to /var/log/syslog on Ubuntu and Debian systems. Filter for cron entries to see what jobs have executed:
grep CRON /var/log/syslog | tail -20
This shows the last 20 cron executions. If a job is not listed at the expected time, investigate the crontab entry syntax, whether cron is running, and whether the script exists and is executable. For Red Hat-based distributions, cron logs may appear in /var/log/cron instead.
Confirming Cron Status
Verify the cron daemon is running:
systemctl status cron
If cron is not running, start it as shown earlier in this article. On some systems, you may need to use crond instead of cron as the service name.
A Practical Example: Automated Database Backup
Automated database backups are one of the most common uses for cron on web servers. Here is a practical example of a daily MySQL backup using cron:
0 3 * * * mysqldump -u root -p'mypassword' mydatabase | gzip > /backups/mydatabase_$(date +\%Y\%m\%d).sql.gz 2>> /var/log/backup-errors.log
Breaking this down: mysqldump outputs the database, | gzip compresses the output, > writes to a file with the date embedded by $(date +\%Y\%m\%d). The backslashes before the percent signs are necessary because cron interprets percent signs specially, converting them to newlines in the command. Error messages are appended to a separate log file using 2>>.
Always back up your database before making significant changes to your server or applications. Test your backup restoration process periodically to ensure your backups are actually usable.
For more complex backup operations, create a separate backup script file rather than putting complex commands directly in the crontab. A script file is easier to test independently, easier to read and maintain, and can be run manually without reconstructing the full command each time.
If you are building automation workflows for your business, understanding how to schedule these tasks reliably can reduce administrative overhead significantly. Many small businesses find that automating routine server tasks reduces the time spent on manual administration and helps prevent important tasks from being forgotten.
Preventing Cron Job Overlaps
By default, cron does not prevent overlapping executions. If a job runs longer than its scheduled interval, the next instance starts anyway. This behaviour can cause problems with resource-intensive tasks or database operations where concurrent access is unsafe.
Use a lock file in your script to prevent overlaps:
[ -f /var/lock/myjob.lock ] && exit 0
trap "rm -f /var/lock/myjob.lock" EXIT
touch /var/lock/myjob.lock
# your job commands here
The trap command ensures the lock file is removed when the script exits, whether it completes normally or is interrupted. This approach is simple and effective for most use cases.
Restricting Cron Access
On shared systems or servers where you need to control which users can schedule cron jobs, use the /etc/cron.deny and /etc/cron.allow files. These files let you grant or restrict cron access at the user level.
If /etc/cron.allow exists, only users listed in that file can use cron. All other users are denied. If only /etc/cron.deny exists, users listed in it are blocked while all others can use cron. The root user can always use cron regardless of these files.
sudo echo "deploy" >> /etc/cron.allow
sudo echo "backup-user" >> /etc/cron.deny
On production servers, it is good practice to restrict cron access to specific service accounts rather than allowing all system users to schedule jobs. This follows the principle of least privilege and reduces the potential impact of a compromised account.
When Cron Might Not Be the Best Solution
Cron is excellent for simple time-based scheduling, but it has limitations that may make it unsuitable for certain use cases.
If you need second-level precision or event-driven scheduling rather than minute-level intervals, a task queue system like Celery with Redis or RabbitMQ may be more appropriate. For containerised environments, Kubernetes CronJobs provide better integration with container orchestration and offer advantages in containerised architectures.
If you need to monitor cron job health, receive alerts on failures, or manage dependencies between tasks, consider a workflow automation tool. These systems provide better visibility into job status and often include retry logic, alerting, and dependency management that cron lacks natively.
Understanding these limitations helps you make informed decisions about where to use cron and where to invest in more sophisticated scheduling tools. Regular IT maintenance schedules that include reviewing your automation tools ensure your server administration practices remain appropriate as your infrastructure grows.
Security Considerations for Cron Jobs
When setting up cron jobs, security should be a consideration alongside functionality. Cron jobs run with the permissions of the user whose crontab they are defined in, which means a compromised script could potentially access resources that user has permission to reach.
Use dedicated service accounts for cron jobs rather than running everything as root. This limits the potential impact if a cron job or its associated script is compromised. Review the permissions of scripts called by cron regularly and ensure they are only writable by the appropriate user.
Avoid putting passwords directly in crontab entries where possible. For database backups, consider using MySQL configuration files with restricted permissions or environment variables set in a secure manner. If a crontab entry must contain sensitive information, ensure the crontab file itself has appropriate permissions.
Setting Up Your First Cron Jobs
Cron is a powerful tool that every Linux server administrator should understand. Start with simple scheduled tasks like daily log rotation or weekly cleanup scripts. Test your scripts in a simulated cron environment before relying on them, and always ensure output goes somewhere useful rather than disappearing silently.
Whether you are managing a single VPS or multiple servers, automating routine tasks with cron frees up time for more valuable work while ensuring critical maintenance happens consistently. The initial investment in setting up reliable automated tasks pays dividends over time through reduced manual effort and improved consistency.
If you need help setting up automated tasks for your server or want a review of your existing cron configuration, you can get in touch with details of your current setup and what you want to automate.