Cron Expression Cheat Sheet β Schedule Like a Pro
Cron is the backbone of scheduled task automation on Unix-like systems. Whether you're rotating logs, running database backups, or triggering CI/CD pipelines, cron expressions define when those jobs execute. The syntax is compact but powerful β and easy to get wrong if you're guessing.
This reference covers every piece of cron syntax with practical, copy-paste examples. If you want to build and validate expressions interactively, open the Cron Expression Builder alongside this guide.
Cron Syntax: The Five Fields
A standard cron expression consists of five fields separated by spaces:
ββββββββββββββ minute (0β59)
β ββββββββββββββ hour (0β23)
β β ββββββββββββββ day of month (1β31)
β β β ββββββββββββββ month (1β12)
β β β β ββββββββββββββ day of week (0β7, where 0 and 7 = Sunday)
β β β β β
* * * * *
Each field accepts a specific value, a range, a list, or a wildcard. Together, the five fields specify an exact recurring schedule.
| Field | Allowed Values | Special Characters |
|---|---|---|
| Minute | 0β59 | * , - / |
| Hour | 0β23 | * , - / |
| Day of Month | 1β31 | * , - / |
| Month | 1β12 | * , - / |
| Day of Week | 0β7 | * , - / |
Month and day-of-week fields also accept three-letter abbreviations (JANβDEC, SUNβSAT) in most implementations.
Special Characters Explained
Understanding four special characters unlocks the full power of cron:
Asterisk * β "Every"
Matches every possible value for that field.
* * * * * # Every minute of every hour of every day
Comma , β "And"
Specifies a list of discrete values.
0 9,12,18 * * * # At 9:00 AM, 12:00 PM, and 6:00 PM daily
Hyphen - β "Through"
Defines an inclusive range.
0 9-17 * * * # Every hour from 9 AM through 5 PM
Slash / β "Every nth"
Sets a step interval from the start of the range.
*/10 * * * * # Every 10 minutes (0, 10, 20, 30, 40, 50)
You can combine a range with a step:
0 9-17/2 * * * # Every 2 hours from 9 AM to 5 PM (9, 11, 13, 15, 17)
Common Cron Schedule Examples
Bookmark this table. These are the schedules you'll use over and over.
| Schedule | Expression | Explanation |
|---|---|---|
| Every minute | * * * * * | Runs at the top of every minute |
| Every 5 minutes | */5 * * * * | Minutes 0, 5, 10, 15, β¦, 55 |
| Every 15 minutes | */15 * * * * | Minutes 0, 15, 30, 45 |
| Every hour | 0 * * * * | At minute 0 of every hour |
| Every 6 hours | 0 */6 * * * | At 00:00, 06:00, 12:00, 18:00 |
| Daily at midnight | 0 0 * * * | Once a day at 00:00 |
| Daily at 3 AM | 0 3 * * * | Once a day at 03:00 |
| Every Monday at 9 AM | 0 9 * * 1 | Weekly on Monday at 09:00 |
| Every weekday at 8 AM | 0 8 * * 1-5 | Monday through Friday at 08:00 |
| Every weekend at noon | 0 12 * * 0,6 | Saturday and Sunday at 12:00 |
| First of every month | 0 0 1 * * | Midnight on the 1st of each month |
| Every quarter (Jan, Apr, Jul, Oct) | 0 0 1 1,4,7,10 * | Midnight on the 1st of quarter months |
| Every 15 min during business hours | */15 9-17 * * 1-5 | Weekdays, 9 AMβ5 PM, every 15 minutes |
Paste any expression into the Cron Expression Builder to visualize the next execution times.
Advanced Patterns
Combining Lists and Ranges
Fields accept mixed syntax. To run a job at 8 AM and 6 PM on weekdays:
0 8,18 * * 1-5
To target specific months with a step:
0 0 1 1-12/3 * # Every 3 months starting January (Jan, Apr, Jul, Oct)
Day-of-Month vs. Day-of-Week
When both day-of-month and day-of-week are set (not *), the behavior depends on the implementation. In standard cron, the job runs if either condition is met β it's an OR relationship, not AND. This catches many people off guard.
0 0 15 * 1 # Runs on the 15th AND every Monday β not "Monday the 15th"
Running at Boot
While not a cron expression per se, @reboot is a widely supported shorthand:
@reboot /usr/local/bin/start-service.sh
Other common shorthands:
| Shorthand | Equivalent |
|---|---|
@yearly | 0 0 1 1 * |
@monthly | 0 0 1 * * |
@weekly | 0 0 * * 0 |
@daily | 0 0 * * * |
@hourly | 0 * * * * |
Cron in Different Environments
The five-field syntax is universal, but how you configure cron varies by platform.
Linux Crontab
The classic. Edit your user crontab with crontab -e:
# Run backup every day at 2 AM
0 2 * * * /home/user/scripts/backup.sh >> /var/log/backup.log 2>&1
System-wide cron jobs in /etc/cron.d/ include an extra user field:
0 2 * * * root /usr/local/bin/cleanup.sh
GitHub Actions
GitHub Actions uses the same five-field syntax inside a schedule trigger. All times are UTC.
on:
schedule:
- cron: '0 3 * * 1-5' # Weekdays at 3 AM UTC
For a deep dive on YAML configuration, see YAML for Kubernetes and YAML for Docker Compose.
Kubernetes CronJob
Kubernetes wraps cron expressions in a CronJob resource:
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: report
image: reporting:latest
command: ["python", "generate_report.py"]
restartPolicy: OnFailure
Kubernetes uses UTC by default. Starting from v1.25, you can set timeZone: "America/New_York" in the CronJob spec.
AWS CloudWatch (EventBridge)
AWS uses a slightly different syntax with six fields (adding seconds) and the rate() / cron() wrappers:
cron(0 3 * * ? *) # Daily at 3 AM UTC
Note the ? character β AWS requires it for either day-of-month or day-of-week when the other is specified. This is different from standard cron.
Common Pitfalls
1. Timezone Confusion
Cron defaults to the system timezone on Linux, but Kubernetes and GitHub Actions run in UTC. A job scheduled for 0 9 * * * will fire at 9 AM UTC, which is 4 AM Eastern or 1 AM Pacific.
Always verify which timezone your scheduler uses. For timestamp conversions, our Unix Timestamp Explained guide covers UTC offsets in detail.
2. Overlapping Executions
If a job takes longer than the interval between runs, you'll get overlapping instances. A script that runs for 8 minutes on a */5 * * * * schedule will stack up.
Solutions:
- Use a lock file (
flockon Linux) - Set
concurrencyPolicy: Forbidin Kubernetes CronJobs - Check for running instances at the start of your script
3. Missing Output and Debugging
Cron doesn't capture stdout by default. Always redirect output:
*/5 * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1
If a cron job isn't running, check:
grep CRON /var/log/syslogfor execution logs- File permissions on the script
- The
PATHenvironment variable β cron has a minimalPATHby default
4. The "31st of Every Month" Trap
0 0 31 * * # Only runs in months with 31 days
This fires in January, March, May, July, August, October, and December β but silently skips the other five months. If you need an end-of-month job, consider running on the 1st and adjusting your script logic, or use a tool that supports "last day of month" semantics.
5. Forgetting Newline at End of Crontab
Some cron implementations require a trailing newline in the crontab file. If your last entry doesn't execute, add an empty line at the end.
Building Expressions Visually
Memorizing syntax works for common patterns, but complex schedules are easier to construct visually. The Cron Expression Builder on alltools.one lets you:
- Select values for each field using dropdowns
- See a human-readable description of the schedule
- Preview upcoming execution times
- Copy the final expression with one click
It runs entirely in your browser β no data is sent to any server.
Quick Reference Card
Copy this block into your project docs or team wiki:
# ββββββ min (0-59)
# β ββββββ hour (0-23)
# β β ββββββ day of month (1-31)
# β β β ββββββ month (1-12)
# β β β β ββββββ day of week (0-7, Sun=0 or 7)
# β β β β β
# * * * * *
*/5 * * * * # Every 5 minutes
0 * * * * # Every hour
0 0 * * * # Daily at midnight
0 9 * * 1-5 # Weekdays at 9 AM
0 0 1 * * # First of the month
*/15 9-17 * * 1-5 # Every 15 min, business hours
Further Reading
- Unix Timestamp Explained β Understand epoch time and timezone conversions
- YAML for Kubernetes β Configure CronJobs and other Kubernetes resources
- YAML for Docker Compose β Schedule containers in compose setups
Ready to build your next cron expression? Open the Cron Expression Builder and get your schedule right the first time.