Complete Guide to Cron Expressions

Master cron syntax with practical examples, scheduling patterns, and best practices for automating tasks

Updated January 2025 · 15 min read

What is Cron?

Cron is a time-based job scheduler in Unix-like operating systems. It enables users to schedule jobs (commands or scripts) to run automatically at specified times, dates, or intervals. The name comes from the Greek word "chronos" meaning time.

Cron is essential for:

Cron Expression Syntax

A standard cron expression consists of 5 fields separated by spaces:

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * * command
Field Required Allowed Values Special Characters
MinuteYes0-59* , - /
HourYes0-23* , - /
Day of MonthYes1-31* , - / ? L W
MonthYes1-12 or JAN-DEC* , - /
Day of WeekYes0-6 or SUN-SAT* , - / ? L #

Special Characters Explained

Asterisk (*) - Any Value

Matches all possible values for the field.

* * * * *    # Every minute
0 * * * *    # Every hour at minute 0

Comma (,) - Multiple Values

Specifies a list of values.

0 8,12,18 * * *    # At 8am, 12pm, and 6pm
0 0 1,15 * *       # 1st and 15th of each month

Hyphen (-) - Range

Specifies a range of values.

0 9-17 * * *       # Every hour from 9am to 5pm
0 0 * * 1-5        # Weekdays at midnight

Slash (/) - Step Values

Specifies increments.

*/5 * * * *        # Every 5 minutes
0 */2 * * *        # Every 2 hours
*/15 9-17 * * *    # Every 15 min during business hours

50+ Common Cron Examples

Every X Minutes

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

Hourly Schedules

0 * * * *Every hour
0 */2 * * *Every 2 hours
0 */4 * * *Every 4 hours
0 */6 * * *Every 6 hours
0 */12 * * *Every 12 hours

Daily Schedules

0 0 * * *Daily at midnight
0 6 * * *Daily at 6am
0 12 * * *Daily at noon
0 18 * * *Daily at 6pm
0 2 * * *Daily at 2am (backups)

Weekly Schedules

0 0 * * 0Every Sunday midnight
0 0 * * 1Every Monday midnight
0 9 * * 1-5Weekdays at 9am
0 0 * * 6,0Weekends at midnight
0 17 * * 5Friday at 5pm

Monthly Schedules

0 0 1 * *1st of month
0 0 15 * *15th of month
0 0 1,15 * *1st and 15th
0 0 1 1,4,7,10 *Quarterly
0 0 1 1 *Yearly (Jan 1st)

Business Hours

0 9-17 * * 1-5Hourly 9-5 weekdays
*/30 9-17 * * 1-5Every 30min business hours
0 9 * * 1-5Weekdays 9am
0 17 * * 1-5Weekdays 5pm

Test Your Cron Expressions

Use our free cron tester to validate expressions and see upcoming execution times.

Open Cron Tester →

Special Strings

Most cron implementations support these convenient shortcuts:

StringEquivalentDescription
@yearly0 0 1 1 *Once a year (Jan 1st midnight)
@annually0 0 1 1 *Same as @yearly
@monthly0 0 1 * *Once a month (1st at midnight)
@weekly0 0 * * 0Once a week (Sunday midnight)
@daily0 0 * * *Once a day (midnight)
@hourly0 * * * *Once an hour
@rebootN/ARun once at startup

Platform Differences

AWS CloudWatch / EventBridge

AWS uses a 6-field format with seconds and year:

# AWS Format: seconds minute hour day month day-of-week year
0 */5 * * * ?      # Every 5 minutes
0 0 12 * * ?       # Daily at noon
0 0 9 ? * MON-FRI  # Weekdays at 9am

Kubernetes CronJob

Kubernetes uses standard 5-field cron with timezone support:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-cronjob
spec:
  schedule: "*/5 * * * *"
  timeZone: "America/New_York"  # K8s 1.27+
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: job
            image: busybox
          restartPolicy: OnFailure

GitHub Actions

GitHub Actions uses standard cron but runs in UTC:

on:
  schedule:
    - cron: '0 0 * * *'  # Daily at midnight UTC
    - cron: '0 9 * * 1-5'  # Weekdays 9am UTC

Best Practices

1. Always Specify Timezone

Cron jobs run in the system's timezone by default. Always document or configure the timezone explicitly:

# In crontab, set timezone
CRON_TZ=America/New_York
0 9 * * * /path/to/script.sh

2. Avoid Overlapping Jobs

Use file locking to prevent multiple instances:

*/5 * * * * flock -n /tmp/myjob.lock /path/to/script.sh

3. Log Output

Always capture output for debugging:

0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1

4. Use Absolute Paths

Cron runs with a minimal PATH. Always use full paths:

# Bad
0 * * * * python script.py

# Good
0 * * * * /usr/bin/python3 /home/user/scripts/script.py

5. Stagger Job Times

Don't schedule everything at :00. Spread load across minutes:

# Instead of all at midnight
0 0 * * * backup_db.sh
0 0 * * * cleanup.sh
0 0 * * * reports.sh

# Stagger them
0 0 * * * backup_db.sh
5 0 * * * cleanup.sh
10 0 * * * reports.sh

Common Mistakes to Avoid

Mistake #1: Using 0 0 31 * * for "last day of month" - This only runs on months with 31 days!

Mistake #2: Forgetting that day-of-week 0 and 7 both mean Sunday in some implementations.

Mistake #3: Assuming jobs run instantly - there can be up to 60 seconds delay.

Mistake #4: Not handling DST transitions - jobs might run twice or not at all during timezone changes.

Testing Tools

Before deploying cron expressions to production, always test them:

Ready to Schedule Your Tasks?

Use our free online cron expression tester to validate and understand your cron schedules.

Test Cron Expressions →

Related Resources