Cron Expression Guide: Master Scheduling Syntax

From basic schedules to complex patterns — everything you need to write, debug, and understand cron expressions.

Developer ToolsApril 11, 20268 min read

What Is a Cron Expression?

A cron expression is a string of five or six fields that defines a schedule. Originally born in Unix's cron daemon (circa 1975), it has become the universal language for task scheduling across Linux, Kubernetes, Spring, Node.js, and cloud platforms.

The classic five-field format covers everything from "run every minute" to "run at 3:17 AM on the second Friday of March." Once you understand the syntax, you can express virtually any recurring schedule in a single line.

The Five Fields, Broken Down

Each cron expression consists of five space-separated fields:

FieldValuesWhat It Controls
Minute0–59Which minute of the hour
Hour0–23Which hour of the day
Day of Month1–31Which day of the month
Month1–12Which month
Day of Week0–6 (Sun–Sat)Which day of the week

Special characters tie these fields together: * (any value), , (list), - (range), / (step), and ? (no specific value, used in some implementations).

Common Patterns You'll Actually Use

Here are the cron expressions that cover 90% of real-world scheduling needs:

# Every minute
* * * * *

# Every 5 minutes
*/5 * * * *

# Hourly, at minute 0
0 * * * *

# Daily at 2:30 AM
30 2 * * *

# Every Monday at 9 AM
0 9 * * 1

# Weekdays at 8 AM and 6 PM
0 8,18 * * 1-5

# First day of every month at midnight
0 0 1 * *

# Every 3 hours during business hours
0 9-17/3 * * 1-5

Day-of-Month vs Day-of-Week: The Classic Trap

The single most common cron mistake: specifying both day-of-month (field 3) and day-of-week (field 5). In standard Linux cron, both conditions are OR'd, not AND'd. So 0 0 15 * 1 means "run at midnight on the 15th OR any Monday" — not "run at midnight on Monday the 15th."

To target a specific day-of-month on a specific weekday, you need a test in the command itself:

# Run only if it's Monday AND the 15th
0 0 15 * 1 test "$(date +\%a)" = "Mon" && /path/to/script.sh

This quirk has burned developers for decades. Always verify your schedule logic in a [cron expression builder](/tools/cron-expression-generator.html) before deploying to production.

Six-Field Variants

Some systems extend the format. Kubernetes CronJobs prepend seconds (0 30 2 * * * for 2:30:00 AM). Spring Framework supports both five and six fields plus optional year. Always check your platform's documentation — a five-field expression pasted into a six-field system will shift every field left by one, producing completely wrong schedules.

Real-World Scheduling Scenarios

Database Backups with Rotation

# Full backup every Sunday at 3 AM
0 3 * * 0 /usr/bin/pg_dump -Fc mydb > /backup/full_$(date +\%F).dump

# Incremental backup weekdays at 3 AM
0 3 * * 1-5 /usr/bin/pg_dump --section=data mydb > /backup/inc_$(date +\%F).dump

# Clean backups older than 30 days, daily at 4 AM
0 4 * * * find /backup -name "*.dump" -mtime +30 -delete

API Health Checks

# Check every 2 minutes, alert on failure
*/2 * * * * curl -sf https://api.example.com/health || \
  curl -X POST https://hooks.slack.com/... -d '{"text":"API down"}'

Log Rotation and Cleanup

# Rotate nginx logs daily at midnight
0 0 * * * /usr/sbin/logrotate /etc/logrotate.d/nginx

# Compress logs older than 7 days
0 1 * * * find /var/log/app -name "*.log" -mtime +7 -exec gzip {} \;

Debugging Cron Jobs: A Checklist

When a cron job silently fails (and they always fail silently), work through these steps:

Cron in Modern Infrastructure

While traditional crontab -e still works, modern deployment patterns often use different wrappers:

Build Expressions Visually

If you're tired of counting asterisks, try a visual cron expression builder. Tools like [RiseTop's cron generator](/tools/cron-expression-generator.html) let you select schedule parameters through dropdowns and checkboxes, then output the correct expression for your platform. It handles the five-field and six-field formats and shows human-readable descriptions like "Every weekday at 9:00 AM."

Key Takeaways