Understanding /etc/cron.d vs /var/spool/cron: Key Differences and Best Practices for Linux Cron Jobs


1 views

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.

  1. Use /etc/cron.d/ for package-maintained or system-critical jobs
  2. Use crontab -e for personal user jobs
  3. Never manually edit files in /var/spool/cron/ - always use the crontab command
  4. 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 (via crontab -e)

Avoid these mistakes:

  1. Never manually edit files in /var/spool/cron - always use crontab -e
  2. Don't mix system and user jobs in the same location
  3. 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/*