In Linux systems, particularly RHEL-based distributions, cron jobs can be configured through two primary locations with distinct purposes:
/etc/cron.d/ # System-wide cron jobs (requires root privileges)
/var/spool/cron/ # User-specific cron jobs (created via crontab -e)
Neither location is "authoritative" - they serve different purposes. The cron daemon reads and executes jobs from both locations. Here's how they differ in practice:
- /etc/cron.d/: Best for system services and packages that need scheduled tasks
- /var/spool/cron/: Designed for individual user crontabs (files are named after usernames)
Example of a system cron in /etc/cron.d/backup:
# System: Daily backup
MAILTO=admin@example.com
0 3 * * * root /usr/local/bin/backup.sh
Example user cron (accessible via crontab -e):
# User: john's personal reminder
0 9 * * 1-5 /home/john/scripts/reminder.sh
For system-wide jobs: Always edit files in /etc/cron.d/ directly (as root). For user-specific jobs, always use crontab -e
which properly handles the /var/spool/cron/ files.
- Use /etc/cron.d/ for package-maintained or system-critical jobs
- Use crontab -e for personal user jobs
- Never manually edit files in /var/spool/cron/ - always use the crontab command
- Include MAILTO in /etc/cron.d/ jobs for proper logging
To verify where a cron job is coming from:
grep -r "backup.sh" /etc/cron* /var/spool/cron/*
Or check active cron jobs for a user:
crontab -l -u username
When working with cron jobs on RHEL-based systems, you'll encounter two primary locations for storing cron configurations: /etc/cron.d
and /var/spool/cron
. These serve different purposes in the Linux scheduling ecosystem.
This system-wide directory is typically used for:
- Package-installed cron jobs (e.g., from RPM or DEB packages)
- System administrator-defined jobs for multiple users
- Jobs that require specific user permissions
# Example /etc/cron.d/example-job
MAILTO=admin@example.com
*/5 * * * * root /usr/local/bin/backup.sh
This user-specific location contains:
- Individual user crontabs created with
crontab -e
- Files named after the user who owns them
- Personal scheduled jobs that don't require root privileges
# Contents might look like this for user 'bob'
0 3 * * * /home/bob/scripts/nightly_cleanup.sh
Feature | /etc/cron.d | /var/spool/cron |
---|---|---|
Ownership | Root-owned | User-owned |
Creation Method | Direct file creation | crontab -e command |
Format | Includes user field | No user field |
Permissions | 644 (root:root) | 600 (user:user) |
Neither location "overrides" the other - they serve different purposes. The authoritative location depends on your use case:
- For system-wide jobs: Use
/etc/cron.d
- For user-specific jobs: Use
/var/spool/cron
(viacrontab -e
)
Avoid these mistakes:
- Never manually edit files in
/var/spool/cron
- always usecrontab -e
- Don't mix system and user jobs in the same location
- Remember to include the MAILTO variable in /etc/cron.d files
For system administrators, I recommend this workflow:
# For system jobs
sudo nano /etc/cron.d/daily_maintenance
# Content:
MAILTO=sysadmin@yourdomain.com
30 4 * * * root /usr/sbin/maintenance.sh
# For user jobs
su - username
crontab -e
# Add user-specific jobs
To verify all active cron jobs across both locations:
# System crons
ls -l /etc/cron.d/
cat /etc/cron.d/*
# User crons
sudo ls -l /var/spool/cron/
sudo cat /var/spool/cron/*