Back to Blog
Tutorialscronschedulingautomation

Cron Expressions Explained: Schedule Tasks Like a Pro

The complete guide to cron expressions. Learn the 5-field syntax, special characters, common patterns, real-world examples, and how to avoid common mistakes.

Loopaloo TeamSeptember 5, 202518 min read

If you've ever needed to run a script automatically at a specific time - like backing up a database every night or sending a weekly report - you've probably encountered cron. This guide will teach you everything you need to know about cron expressions, from the basics to advanced patterns.

What is Cron?

Cron is a time-based job scheduler built into Unix-like operating systems (Linux, macOS). It runs in the background and executes commands or scripts at scheduled times.

The name "cron" comes from the Greek word "chronos" (time). A cron job is a scheduled task, and a cron expression (also called a cron schedule) defines when that task runs.

Common uses for cron jobs:

  • Automated backups
  • Sending scheduled emails or reports
  • Clearing temporary files
  • Syncing data between systems
  • Running health checks
  • Renewing SSL certificates

Anatomy of a Cron Expression

A standard cron expression has 5 fields separated by spaces:

+--------------- minute (0-59)
| +------------- hour (0-23)
| | +----------- day of month (1-31)
| | | +--------- month (1-12)
| | | | +------- day of week (0-6, where 0 = Sunday)
| | | | |
* * * * *

Each field specifies when the job should run. Let's break down each one:

Field 1: Minute (0-59)

The minute of the hour when the job runs.

ValueMeaning
0At the top of the hour (XX:00)
30At half past the hour (XX:30)
*/15Every 15 minutes
0,30At :00 and :30

Field 2: Hour (0-23)

The hour of the day in 24-hour format.

ValueMeaning
0Midnight (12:00 AM)
99:00 AM
175:00 PM
2311:00 PM

Field 3: Day of Month (1-31)

The day of the month.

ValueMeaning
1First day of the month
1515th of the month
1,151st and 15th

Field 4: Month (1-12)

The month of the year. You can use numbers or three-letter abbreviations.

ValueMeaning
1 or JANJanuary
6 or JUNJune
12 or DECDecember
1-6January through June

Field 5: Day of Week (0-6)

The day of the week, where Sunday is 0 (or 7 on some systems).

ValueDay
0 or SUNSunday
1 or MONMonday
2 or TUETuesday
3 or WEDWednesday
4 or THUThursday
5 or FRIFriday
6 or SATSaturday

Special Characters Explained

Cron expressions use special characters to create flexible schedules:

Asterisk (*) - Any Value

Matches all possible values for that field.

* * * * *    # Every minute of every hour of every day
0 * * * *    # Every hour (at minute 0)
0 0 * * *    # Every day at midnight

Comma (,) - Multiple Values

Specifies a list of values.

0 9,17 * * *     # At 9 AM and 5 PM
0 0 1,15 * *     # On the 1st and 15th of each month
0 0 * * 1,3,5    # Every Monday, Wednesday, and Friday

Hyphen (-) - Range of Values

Specifies a range from start to end (inclusive).

0 9-17 * * *     # Every hour from 9 AM to 5 PM
0 0 * * 1-5      # Every weekday (Monday through Friday)
0 0 1-7 * *      # First 7 days of each month

Slash (/) - Step Values

Specifies intervals. "Start/step" means "starting at start, every step."

*/5 * * * *      # Every 5 minutes
0 */2 * * *      # Every 2 hours (at :00)
*/10 9-17 * * *  # Every 10 minutes during business hours
0 0 */3 * *      # Every 3 days

Combining Characters

You can combine these characters for complex schedules:

0,30 9-17 * * 1-5    # At :00 and :30, 9 AM-5 PM, weekdays only
*/15 8-20 * * *      # Every 15 min during extended hours
0 6,12,18 1,15 * *   # 6 AM, noon, 6 PM on 1st and 15th

Common Cron Patterns

Here are the most frequently used cron expressions:

Every X Minutes

* * * * *        # Every minute
*/5 * * * *      # Every 5 minutes
*/10 * * * *     # Every 10 minutes
*/15 * * * *     # Every 15 minutes
*/30 * * * *     # Every 30 minutes

Hourly

0 * * * *        # Every hour (at :00)
30 * * * *       # Every hour (at :30)
0 */2 * * *      # Every 2 hours
0 */6 * * *      # Every 6 hours (midnight, 6 AM, noon, 6 PM)

Daily

0 0 * * *        # Every day at midnight
0 6 * * *        # Every day at 6 AM
0 12 * * *       # Every day at noon
0 18 * * *       # Every day at 6 PM
30 4 * * *       # Every day at 4:30 AM

Weekly

0 0 * * 0        # Every Sunday at midnight
0 9 * * 1        # Every Monday at 9 AM
0 0 * * 1-5      # Every weekday at midnight
0 17 * * 5       # Every Friday at 5 PM
0 10 * * 6,0     # Every weekend at 10 AM

Monthly

0 0 1 * *        # First day of every month at midnight
0 9 1 * *        # First day of every month at 9 AM
0 0 15 * *       # 15th of every month at midnight
0 0 1,15 * *     # 1st and 15th of every month
0 0 L * *        # Last day of every month (if supported)

Yearly

0 0 1 1 *        # January 1st at midnight (New Year)
0 0 1 6 *        # June 1st at midnight
0 0 25 12 *      # December 25th at midnight

Real-World Examples

System Maintenance

# Clear temp files every day at 3 AM
0 3 * * * /usr/local/bin/cleanup-temp.sh

# Rotate logs weekly on Sunday at 2 AM
0 2 * * 0 /usr/sbin/logrotate /etc/logrotate.conf

# Reboot server monthly on the 1st at 4 AM
0 4 1 * * /sbin/reboot

Backups

# Database backup every night at 2 AM
0 2 * * * /scripts/backup-db.sh

# Full backup every Sunday at 1 AM
0 1 * * 0 /scripts/full-backup.sh

# Incremental backup weekdays at 1 AM
0 1 * * 1-5 /scripts/incremental-backup.sh

Reports and Notifications

# Daily report at 8 AM
0 8 * * * /scripts/daily-report.sh

# Weekly summary every Monday at 9 AM
0 9 * * 1 /scripts/weekly-summary.sh

# Monthly invoice on the 1st at 6 AM
0 6 1 * * /scripts/generate-invoices.sh

Application Tasks

# Check for updates every 6 hours
0 */6 * * * /app/check-updates.sh

# Sync data every 15 minutes during business hours
*/15 9-17 * * 1-5 /app/sync-data.sh

# Send digest email every evening at 6 PM
0 18 * * * /app/send-digest.sh

# Expire sessions every hour
0 * * * * /app/expire-sessions.sh

SSL and Security

# Renew SSL certificates (weekly check)
0 3 * * 1 certbot renew --quiet

# Security scan every night at 1 AM
0 1 * * * /scripts/security-scan.sh

# Update virus definitions every 4 hours
0 */4 * * * freshclam

Extended Cron Syntax

Some systems support additional fields and features:

6-Field Cron (with Seconds)

Some schedulers (like Quartz, Spring, node-cron) support seconds as the first field:

+---------------- second (0-59)
| +-------------- minute (0-59)
| | +------------ hour (0-23)
| | | +---------- day of month (1-31)
| | | | +-------- month (1-12)
| | | | | +------ day of week (0-6)
| | | | | |
* * * * * *
*/30 * * * * *   # Every 30 seconds
0 */5 * * * *    # Every 5 minutes (at :00 seconds)
0 0 * * * *      # Every hour (at :00:00)

7-Field Cron (with Year)

Some enterprise schedulers add a year field:

0 0 1 1 * 2025   # January 1, 2025 at midnight

Special Strings

Many cron implementations support convenient shortcuts:

StringEquivalentDescription
@yearly or @annually0 0 1 1 *Once a year (Jan 1, midnight)
@monthly0 0 1 * *Once a month (1st, midnight)
@weekly0 0 * * 0Once a week (Sunday, midnight)
@daily or @midnight0 0 * * *Once a day (midnight)
@hourly0 * * * *Once an hour (at :00)
@rebootN/AOnce at startup

Common Mistakes to Avoid

1. Forgetting About Timezones

Cron runs in the server's timezone, which might differ from your local time.

# If your server is in UTC but you want 9 AM EST:
# EST is UTC-5, so use hour 14 (9 + 5)
0 14 * * * /scripts/morning-task.sh

Tip: Use timedatectl to check your server's timezone.

2. Day of Month AND Day of Week Confusion

When you specify both day of month AND day of week, cron runs when EITHER condition is met (OR logic), not both (AND logic).

# This runs on the 15th AND every Friday, not "15th if it's Friday"
0 0 15 * 5 /scripts/task.sh

# To run only on the 15th, ignore day of week:
0 0 15 * * /scripts/task.sh

3. Not Escaping Special Characters

In crontab, the percent sign (%) has special meaning (newline). Escape it:

# Wrong - % will break this
0 0 * * * echo "Today is $(date +%Y-%m-%d)"

# Correct - escape the %
0 0 * * * echo "Today is $(date +\%Y-\%m-\%d)"

4. Not Using Full Paths

Cron runs with a minimal environment. Always use absolute paths:

# Wrong - might not find the command
0 * * * * node /app/script.js

# Correct - use full path
0 * * * * /usr/bin/node /app/script.js

5. Overlapping Jobs

If a job takes longer than its interval, instances can pile up:

# If backup takes 10 minutes but runs every 5...
*/5 * * * * /scripts/long-backup.sh  # Problem!

# Use flock to prevent overlapping
*/5 * * * * /usr/bin/flock - n /tmp/backup.lock /scripts/long-backup.sh

How to Set Up Cron Jobs

Editing Your Crontab

# Edit your user's crontab
crontab - e

# View your crontab
crontab - l

# Remove all cron jobs
crontab - r

Crontab File Format

Each line in a crontab follows this format:

# Comment lines start with #
MAILTO="you@example.com"  # Optional: email output

# m h dom mon dow command
0 5 * * * /scripts/backup.sh
*/15 * * * * /scripts/monitor.sh

System-Wide Cron

System cron jobs include a user field:

# /etc/crontab or files in /etc/cron.d/
# m h dom mon dow user command
0 5 * * * root /scripts/backup.sh

Logging Output

Capture output for debugging:

# Log both stdout and stderr
0 * * * * /scripts/task.sh >> /var/log/task.log 2>&1

# Discard output (silent)
0 * * * * /scripts/task.sh > /dev/null 2>&1

Testing Cron Expressions

Before deploying, always verify your expression means what you think:

  1. Use online tools - Our Cron Expression Builder shows the next scheduled runs
  2. Check with systemctl - View recent runs: systemctl status cron
  3. Test with short intervals - Start with * * * * * (every minute) to verify the job works

Quick Reference

ScheduleExpression
Every minute* * * * *
Every 5 minutes*/5 * * * *
Every hour0 * * * *
Every day at midnight0 0 * * *
Every day at 9 AM0 9 * * *
Every Monday at 9 AM0 9 * * 1
Weekdays at 9 AM0 9 * * 1-5
First of month at midnight0 0 1 * *
Every Sunday at midnight0 0 * * 0
Every 6 hours0 */6 * * *
Twice daily (9 AM and 6 PM)0 9,18 * * *

Key Takeaways

  1. Five fields: minute, hour, day of month, month, day of week
  2. Special characters: * (any), , (list), - (range), / (step)
  3. Always use absolute paths in cron commands
  4. Mind the timezone - cron uses server time
  5. Test before deploying - verify the schedule is correct
  6. Log output - makes debugging much easier
  7. Prevent overlaps - use flock for long-running jobs

Use our Cron Expression Builder to create, validate, and understand cron expressions visually.

Related Tools

Related Articles

Try Our Free Tools

200+ browser-based tools for developers and creators. No uploads, complete privacy.

Explore All Tools