Understanding Cron Syntax: Schedule Tasks Like a Pro
Cron is the standard task scheduler on Unix-like systems, and cron expressions are used everywhere — Linux crontabs, GitHub Actions, Kubernetes CronJobs, AWS EventBridge, and CI/CD pipelines. The syntax looks cryptic at first, but it follows a simple pattern. This guide covers everything from basic schedules to advanced expressions.
Cron Expression Format
A standard cron expression has 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)
│ │ │ │ │
* * * * * | Field | Values | Special Characters |
|---|---|---|
| Minute | 0-59 | * , - / |
| Hour | 0-23 | * , - / |
| Day of month | 1-31 | * , - / L W |
| Month | 1-12 or JAN-DEC | * , - / |
| Day of week | 0-7 or SUN-SAT | * , - / L # |
Special Characters
| Character | Meaning | Example |
|---|---|---|
* | Any value | * * * * * = every minute |
, | Value list | 1,15 * * * * = minute 1 and 15 |
- | Range | 1-5 * * * * = minutes 1 through 5 |
/ | Step | */15 * * * * = every 15 minutes |
L | Last | 0 0 L * * = last day of month |
W | Nearest weekday | 0 0 15W * * = nearest weekday to the 15th |
# | Nth day of week | 0 0 * * 5#3 = third Friday |
Note: L, W, and # are extensions not available in all cron implementations. Standard Unix cron supports * , - / only.
20 Practical Examples
Basic Intervals
# Every minute
* * * * *
# Every 5 minutes
*/5 * * * *
# Every 15 minutes
*/15 * * * *
# Every hour (at minute 0)
0 * * * *
# Every 30 minutes
0,30 * * * * Specific Times
# Every day at midnight
0 0 * * *
# Every day at 9:00 AM
0 9 * * *
# Every day at 2:30 PM
30 14 * * *
# Twice a day (9 AM and 5 PM)
0 9,17 * * *
# Every day at 6 AM, 12 PM, and 6 PM
0 6,12,18 * * * Day-Specific Schedules
# Every Monday at 9 AM
0 9 * * 1
# Weekdays at 8 AM (Mon-Fri)
0 8 * * 1-5
# Weekends at 10 AM
0 10 * * 0,6
# First day of every month at midnight
0 0 1 * *
# Every quarter (Jan, Apr, Jul, Oct) on the 1st at midnight
0 0 1 1,4,7,10 * Complex Schedules
# Every weekday during business hours (every 30 min, 9 AM - 5 PM)
*/30 9-17 * * 1-5
# Every Sunday at 2 AM (weekly backup)
0 2 * * 0
# Every 6 hours
0 */6 * * *
# Last day of every month at 11:59 PM (requires L support)
59 23 L * *
# Every 10 minutes during business hours on weekdays
*/10 9-17 * * 1-5 Six-Field Cron (With Seconds)
Some systems (Spring, Quartz, AWS) support a sixth field for seconds:
┌───────────── second (0-59)
│ ┌───────────── minute (0-59)
│ │ ┌───────────── hour (0-23)
│ │ │ ┌───────────── day of month (1-31)
│ │ │ │ ┌───────────── month (1-12)
│ │ │ │ │ ┌───────────── day of week (0-7)
│ │ │ │ │ │
* * * * * *
# Every 30 seconds
*/30 * * * * *
# At second 0 of every minute (same as 5-field)
0 * * * * * Cron in Different Systems
Linux Crontab
# Edit your crontab
crontab -e
# List your cron jobs
crontab -l
# Example entry with output logging
0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
# Example with PATH set
PATH=/usr/local/bin:/usr/bin:/bin
0 * * * * python3 /home/user/script.py GitHub Actions
on:
schedule:
# Runs at 00:00 UTC every day
- cron: '0 0 * * *'
# Runs every Monday at 9 AM UTC
- cron: '0 9 * * 1' Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-cleanup
spec:
schedule: "0 3 * * *" # 3 AM daily
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup
image: busybox
command: ["/bin/sh", "-c", "echo Cleaning up"]
restartPolicy: OnFailure Node.js (node-cron)
const cron = require('node-cron');
// Run every day at midnight
cron.schedule('0 0 * * *', () => {
console.log('Running daily task');
});
// Run every 5 minutes
cron.schedule('*/5 * * * *', () => {
console.log('Running every 5 minutes');
}); Common Pitfalls
- Time zones matter — Linux cron uses the system timezone. GitHub Actions uses UTC. Kubernetes uses UTC. AWS uses UTC. Always check which timezone your cron system uses.
- Day-of-month and day-of-week combine with OR —
0 0 15 * 5runs on the 15th and every Friday, not "the 15th if it's a Friday." - Environment is minimal — cron jobs run with a limited
PATH. Always use full paths to executables or setPATHexplicitly. - No output by default — redirect stdout/stderr to a log file or
/dev/nullto avoid cron sending emails. - Overlapping runs — if a job takes longer than the interval, you'll have multiple instances running. Use
flockfor locking.
Predefined Shortcuts
Many cron implementations support these shortcuts:
| Shortcut | Equivalent | Description |
|---|---|---|
@yearly | 0 0 1 1 * | Once a year (Jan 1st, midnight) |
@monthly | 0 0 1 * * | Once a month (1st, midnight) |
@weekly | 0 0 * * 0 | Once a week (Sunday, midnight) |
@daily | 0 0 * * * | Once a day (midnight) |
@hourly | 0 * * * * | Once an hour (minute 0) |
@reboot | — | Run once at system startup |
The syntax of cron expressions shares some concepts with regular expressions — both use special characters to define patterns. The * wildcard and range syntax (1-5) work similarly in both contexts.
Building cron expressions by hand is error-prone. Use our Cron Expression Generator to visually build and validate cron schedules — see exactly when your job will run next without guessing. Need to convert between cron timestamps and human dates? Our Epoch Converter can help.