Complete Guide to Cron Expressions - Master Cron Job Scheduling 2026
Master cron expressions with this comprehensive guide. Learn complete syntax, 10 real-world examples, debugging tips, and 2026 best practices. Perfect for developers and DevOps engineers.
Learn by doing
Practice with the Cron Expression Generator while reading - free, no registration required
Cron is one of the most powerful and widely used scheduling tools in Unix/Linux systems. Whether you're automating backups, generating reports, or running periodic maintenance tasks, understanding cron expressions is essential for any developer or system administrator.
This comprehensive guide will take you from beginner to expert in cron job scheduling. You'll learn the complete syntax, discover time-saving shortcuts, avoid common pitfalls, and master advanced techniques that most developers never learn.
By the end of this guide, you'll be able to create complex scheduling patterns with confidence, troubleshoot issues like a pro, and follow industry-standard best practices for production environments.
Understanding Cron Syntax
A cron expression is a string of 5 or 6 fields separated by spaces. Each field represents a unit of time, and the combination determines when the scheduled task will run.
Basic Format
The standard cron format consists of 5 fields: minute, hour, day of month, month, and day of week. This format is used by most Unix/Linux systems in their crontab files.
Extended Format
Some systems support a 6-field format that includes seconds as the first field. This is commonly used in Kubernetes CronJobs and modern schedulers like AWS EventBridge.
The 5 Cron Fields
Each field in a cron expression has a specific range and meaning. Understanding these fields is fundamental to writing accurate cron expressions.
Field Format
* * * * *
│ │ │ │ │
│ │ │ │ └─ Day of week (0-7, 0 and 7 = Sunday)
│ │ │ └───── Month (1-12)
│ │ └───────── Day of month (1-31)
│ └──────────── Hour (0-23)
└─────────────── Minute (0-59)
Special Characters
Cron expressions use special characters to define flexible scheduling patterns. Mastering these characters allows you to create complex schedules with minimal effort.
Asterisk (*)
The asterisk means "every" or "all values" in that field. For example, * in the hour field means "every hour".
Slash (/)
The slash is used to define steps or intervals. */5 means "every 5 units". Combined with *, it creates repeating patterns.
Comma (,)
The comma separates multiple values. 1,3,5 means "at 1, 3, and 5". Useful for specifying specific times.
Hyphen (-)
The hyphen defines a range. 1-5 means "from 1 through 5 inclusive". Can be combined with other characters.
Question Mark (?)
Used only in the day of week field in some cron implementations. It means "no specific value" and is typically used with day of month.
Predefined Expressions
Cron includes special keywords that replace complex numeric expressions. These shortcuts make common schedules more readable and easier to maintain.
Common Predefined Keywords
@yearly (or @annually) = Run once a year at midnight January 1
= 0 0 1 1 *
@monthly = Run once a month at midnight on first day
= 0 0 1 * *
@weekly = Run once a week at midnight on Sunday
= 0 0 * * 0
@daily (or @midnight) = Run once a day at midnight
= 0 0 * * *
@hourly = Run once an hour at the beginning of the hour
= 0 * * * *
@reboot = Run once at startup (not time-based)
Real-World Examples
These examples demonstrate practical cron expressions used in production environments. Each example solves a specific scheduling challenge.
Database Backup - Daily at 2 AM
# crontab entry
0 2 * * * /usr/bin/pg_dump mydb > /backups/db_$(date +\%Y\%m\%d).sql
Log Cleanup - Weekly on Sunday
# crontab entry
0 3 * * 0 find /var/log/*.log -mtime +30 -delete
Report Generation - First Day of Month
# crontab entry
0 8 1 * * /usr/bin/python3 /scripts/generate_monthly_report.sh
Health Check - Every 5 Minutes
# crontab entry
*/5 * * * * curl -f http://localhost:8080/health || echo "Service down" | mail -s "Alert" [email protected]
Data Sync - Hourly
# crontab entry
0 * * * * /usr/bin/rsync -av /data/ backup@remote:/data
Cache Clear - Weekdays at 6 PM
# crontab entry
0 18 * * 1-5 /usr/bin/redis-cli FLUSHALL
Email Report - Every Friday at 4 PM
# crontab entry
0 16 * * 5 /usr/bin/sendemail "Weekly Report" < [email protected]
Temporary Task - Only in March
# crontab entry
0 12 * 3 * /scripts/maintenance_task.sh
Multiple Times - 6 AM, 2 PM, 8 PM
# crontab entry
0 6,14,20 * * * /scripts/check_status.sh
Complex Interval - Every 15 Minutes on Weekdays
# crontab entry
*/15 * * * 1-5 /scripts/business_hours_check.sh
Debugging Cron Jobs
When a cron job doesn't run as expected, systematic debugging saves hours of frustration. Follow this structured approach to identify and fix issues quickly.
Check Cron Syntax
Validate your cron expression using online tools or the crontab -l command. Even a single space or wrong character can prevent execution.
Verify File Permissions
Ensure the script is executable (chmod +x) and has proper read/write permissions. Cron jobs run with limited user privileges.
Check System Logs
Review /var/log/syslog or /var/log/cron for error messages. These logs often reveal permission issues, missing commands, or execution failures.
Test Environment Variables
Cron jobs run with a minimal environment. Always use full paths for commands and explicitly set required environment variables in the crontab or script.
Verify Timezone
Cron uses UTC by default. Convert your local time to UTC or set the TZ environment variable in your crontab file.
Cron Variants
Different systems implement cron differently. Understanding these variants helps you work across various platforms and tools.
Traditional Unix Cron
The original cron system uses the 5-field format and is configured via /etc/crontab files. It's reliable and available on all Unix/Linux systems.
Systemd Timers
Modern Linux distributions use systemd timers as an alternative to cron. They offer more precise scheduling, better logging, and dependency management between services.
Kubernetes CronJob
Kubernetes implements cron-like scheduling with additional features like concurrency policies, deadlines, and suspensions. Uses a 6-field format including seconds.
Quartz Scheduler
Popular in Java applications, Quartz offers cron-like expressions with additional features for enterprise scheduling, job persistence, and clustering.
2026 Best Practices
Follow these industry-standard practices to create reliable, maintainable, and secure cron jobs.
Always Use Absolute Paths
Specify full paths to scripts and commands to avoid issues with limited cron environment PATH.
Redirect Output to Logs
Always redirect both stdout and stderr to log files for troubleshooting: >> /var/log/job.log 2>&1
Set MAILTO Variable
Configure email notifications for cron job failures: [email protected] in your crontab file.
Use Lock Files
Prevent overlapping executions for long-running jobs with lock files using flock or similar mechanisms.
Add Comments
Document what each cron job does, why it runs at that time, and who to contact for issues. This helps future maintenance.
Test Before Deploying
Always test your script manually before scheduling it with cron. This catches syntax errors and logic issues early.
Quick Reference
Keep this handy reference nearby when working with cron expressions. It covers the most common patterns and their meanings.
Real-World Examples
Case Study 1: Automated Database Backup
Problem
A startup needed reliable daily backups of their PostgreSQL database, but the backup script failed randomly when run through cron.
Solution
The issue was that pg_dump required environment variables (PGPASSWORD, PGUSER) that weren't set in the cron environment. Fixed by adding environment variables in the crontab file and using absolute paths.
0 2 * * * /usr/bin/env PGPASSWORD=pass /usr/bin/pg_dump -U user mydb > /backups/db.sql 2>&1
Case Study 2: Server Health Monitoring
Problem
Health check script ran successfully manually but failed when scheduled with cron.
Solution
Discovered that the script used curl to check http://localhost:8080/health, but the service wasn't running when cron executed (3 AM UTC, before service startup). Fixed by adding service startup check and timeout handling.
*/5 * * * * /usr/bin/curl -f --max-time 10 http://localhost:8080/health || echo "Service not running" | /usr/bin/logger -t health_check
Case Study 3: Log Rotation with Retention
Problem
Server disk filled up because old logs weren't being deleted despite having a cleanup job in cron.
Solution
The log cleanup job ran correctly but used wrong mtime parameters. Was using -mtime +30 (files older than 30 days) but the script created logs in a way that reset modification times. Fixed by using -ctime instead and adding log rotation in the application itself.
0 3 * * * find /var/log/app/*.log -ctime +30 -delete -print 2>&1 | tee -a /var/log/cleanup.log
Best Practices
Use Absolute Paths
Always specify complete paths to avoid PATH issues in cron's minimal environment
✓ Do: /usr/local/bin/python3 /scripts/task.sh
✗ Don't: python3 /scripts/task.sh
Redirect All Output
Capture both stdout and stderr to logs for debugging and auditing
✓ Do: /script.sh >> /var/log/script.log 2>&1
✗ Don't: /script.sh
Set Lock Files
Prevent overlapping executions that could cause data corruption
✓ Do: flock -n /tmp/script.lock -c "/script.sh"
✗ Don't: /script.sh & (allow overlaps)
Add Comments
Document purpose, owner, and last modified date for maintainability
✓ Do: # Daily database backup - Contact: [email protected] - Modified: 2026-02-08
✗ Don't: (no comments)
Test Timezone
Verify cron executes in the expected timezone
✓ Do: CRON_TZ=America/New_York 0 9 * * * /script.sh
✗ Don't: 0 9 * * * /script.sh (may use unexpected timezone)
Use Lock Files
Prevent cron from running if previous instance still active
✓ Do: */15 * * * * /usr/bin/flock -xn /tmp/myjob.lock -c "/path/to/job.sh"
✗ Don't: */15 * * * * /path/to/job.sh (runs even if previous still running)
Quick Checklist
Before Creating Cron Job
- Test script manually to verify it works
- Use absolute paths for all commands and files
- Set appropriate file permissions (chmod +x)
- Add shebang line (#!/bin/bash or #!/usr/bin/env python3)
- Test with different user if needed
When Adding to Crontab
- Validate cron expression syntax
- Set MAILTO variable for error notifications
- Add descriptive comments
- Set correct timezone with CRON_TZ if needed
- Add output redirection to log file
- Use full paths in commands
After Deployment
- Check logs for first execution
- Verify output files are created
- Monitor system resources usage
- Test backup/restore procedures
- Document job purpose and maintenance procedures
- Set up monitoring/alerts for failures
Maintenance
- Review cron logs weekly
- Update scripts and dependencies
- Rotate and archive log files
- Test disaster recovery procedures
- Update documentation when making changes
Frequently Asked Questions
What's the difference between */5 and 0/5 in cron? ▼
How do I run a cron job every 30 seconds? ▼
Why is my cron job one hour off? ▼
Can I run a cron job as a specific user? ▼
How do I schedule a job on the last day of every month? ▼
What happens if my system is off during a scheduled cron time? ▼
How can I see all scheduled cron jobs? ▼
Is cron secure for production environments? ▼
How do I temporarily disable a cron job without deleting it? ▼
Can cron jobs run in parallel? ▼
Further Reading
Master Cron Expression Generator Today
Put your knowledge into practice with our free, privacy-focused tools
Try Cron Expression Generator →