DEV Community

楊東霖
楊東霖

Posted on • Originally published at devtoolkit.cc

Cron Expression Cheat Sheet & Examples

Cron expressions are the backbone of scheduled tasks in Unix, Linux, macOS, CI/CD pipelines, cloud functions, and container orchestration. They look cryptic at first — 0 */6 * * 1-5 — but once you understand the five (or six) fields, you can schedule anything.

This cheat sheet covers the standard 5-field cron syntax, extended 6-field syntax (with seconds), every special character, and dozens of real-world examples you can copy-paste into your crontab, GitHub Actions, or Kubernetes CronJob.

Cron Syntax: The 5 Fields

A standard cron expression has five fields separated by spaces:

┌───────────── minute (059)
│ ┌───────────── hour (023)
│ │ ┌───────────── day of month (131)
│ │ │ ┌───────────── month (112 or JANDEC)
│ │ │ │ ┌───────────── day of week (07 or SUNSAT, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *
Enter fullscreen mode Exit fullscreen mode

Each field can contain a single value, a range, a list, a step, or a wildcard. The expression fires when all five fields match the current time.

Special Characters Explained

Character Meaning Example
`*` Any value `* * * * *` — every minute
`,` List separator `0 8,12,18 * * *` — at 8am, noon, 6pm
`-` Range `0 9-17 * * *` — every hour from 9am to 5pm
`/` Step `*/15 * * * *` — every 15 minutes
`L` Last (non-standard) `0 0 L * *` — last day of month
`W` Nearest weekday (non-standard) `0 0 15W * *` — nearest weekday to 15th
`#` Nth weekday (non-standard) `0 0 * * 5#3` — third Friday of month
`?` No specific value (Quartz) `0 0 * * ?` — any day of week

Note: L, W, #, and ? are extensions used in Quartz (Java), Spring, and some cloud platforms. Standard Unix crontab only supports *, ,, -, and /.

Common Cron Patterns

Here are the patterns you'll use most often, ready to copy-paste.

Every X Minutes

* * * * *        # Every minute
*/5 * * * *      # Every 5 minutes
*/15 * * * *     # Every 15 minutes
*/30 * * * *     # Every 30 minutes
0 * * * *        # Every hour (at minute 0)
Enter fullscreen mode Exit fullscreen mode

Daily Schedules

0 0 * * *        # Midnight daily
0 6 * * *        # 6:00 AM daily
30 8 * * *       # 8:30 AM daily
0 12 * * *       # Noon daily
0 23 * * *       # 11:00 PM daily
0 0,12 * * *     # Midnight and noon
Enter fullscreen mode Exit fullscreen mode

Weekly Schedules

0 0 * * 0        # Midnight every Sunday
0 9 * * 1        # 9 AM every Monday
0 9 * * 1-5      # 9 AM every weekday (Mon–Fri)
0 18 * * 5       # 6 PM every Friday
0 10 * * 6,0     # 10 AM every Saturday and Sunday
Enter fullscreen mode Exit fullscreen mode

Monthly and Yearly Schedules

0 0 1 * *        # Midnight on the 1st of every month
0 9 15 * *       # 9 AM on the 15th of every month
0 0 1 1 *        # Midnight on January 1st (yearly)
0 0 1 */3 *      # Midnight on the 1st, every 3 months (quarterly)
0 0 1 1,4,7,10 * # Midnight on the 1st of each quarter
Enter fullscreen mode Exit fullscreen mode

Business Hours

*/10 9-17 * * 1-5    # Every 10 min during business hours (Mon–Fri 9am–5pm)
0 9-17 * * 1-5       # Every hour during business hours
0 9,13 * * 1-5       # 9 AM and 1 PM on weekdays
30 8 * * 1-5         # 8:30 AM on weekdays (daily standup time)
Enter fullscreen mode Exit fullscreen mode

Extended 6-Field Syntax (Seconds)

Some systems (Quartz, Spring, AWS EventBridge) support a sixth field for seconds:

┌───────────── second (059)
│ ┌───────────── minute (059)
│ │ ┌───────────── hour (023)
│ │ │ ┌───────────── day of month (131)
│ │ │ │ ┌───────────── month (112)
│ │ │ │ │ ┌───────────── day of week (07)
│ │ │ │ │ │
* * * * * *
Enter fullscreen mode Exit fullscreen mode
*/30 * * * * *    # Every 30 seconds
0 */5 * * * *     # Every 5 minutes (at second 0)
0 0 * * * *       # Every hour (at second 0, minute 0)
Enter fullscreen mode Exit fullscreen mode

Warning: Standard Unix crontab does NOT support seconds. If you need sub-minute scheduling on Linux, use a workaround like running a script every minute that internally sleeps.

Cron in Different Environments

Linux / macOS Crontab

Edit your crontab with crontab -e:

# Backup database every night at 2 AM
0 2 * * * /usr/local/bin/backup-db.sh >> /var/log/backup.log 2>&1

# Clean temp files every Sunday at 3 AM
0 3 * * 0 find /tmp -mtime +7 -delete

# Health check every 5 minutes
*/5 * * * * curl -fsS https://hc-ping.com/your-uuid > /dev/null
Enter fullscreen mode Exit fullscreen mode

Key crontab tips:

  • Always redirect output (> /dev/null 2>&1) or cron will email you on every run.
  • Use full paths for commands — cron's PATH is minimal.
  • Set MAILTO="" at the top to disable email notifications entirely.
  • Use crontab -l to list current jobs, crontab -r to remove all.

GitHub Actions

on:
  schedule:
    - cron: '0 6 * * 1-5'   # 6 AM UTC, weekdays
    - cron: '0 0 1 * *'     # Midnight UTC, 1st of month
Enter fullscreen mode Exit fullscreen mode

GitHub Actions uses UTC only. Runs may be delayed by up to 15 minutes during peak load. Minimum interval is 5 minutes, but GitHub may throttle more frequent schedules.

Kubernetes CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-report
spec:
  schedule: "0 8 * * *"        # 8 AM daily
  concurrencyPolicy: Forbid     # Don't overlap runs
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: report
            image: myapp/report:latest
            command: ["python", "generate_report.py"]
          restartPolicy: OnFailure
Enter fullscreen mode Exit fullscreen mode

AWS CloudWatch / EventBridge

AWS uses a slightly different syntax with 6 fields (year is optional):

cron(0 18 ? * MON-FRI *)     # 6 PM UTC, weekdays
cron(0 12 1 * ? *)           # Noon UTC on the 1st of each month
rate(5 minutes)               # Alternative: every 5 minutes (simpler)
Enter fullscreen mode Exit fullscreen mode

Note that AWS uses ? for "no specific value" in either day-of-month or day-of-week (you must use ? in exactly one of them).

Debugging Cron Expressions

The most common cron bugs:

  • Timezone confusion. Crontab runs in the system's local timezone. GitHub Actions and AWS use UTC. Always document which timezone your cron uses.

  • Day-of-month AND day-of-week. In standard cron, if both are set (not *), the job runs when either matches — not both. This catches people off guard. 0 0 15 * 5 runs on the 15th AND every Friday.

  • February 30th. 0 0 30 2 * will never fire. Cron silently skips impossible dates.

  • Step misunderstanding. */7 * * * * does NOT run every 7 minutes starting from the last run. It runs at minutes 0, 7, 14, 21, 28, 35, 42, 49, 56. The step divides the range, not the interval from last execution.

  • Overlapping runs. If a job takes 10 minutes but runs every 5, you'll get overlapping executions. Use a lock file or concurrencyPolicy: Forbid in Kubernetes.

Advanced Patterns

First and Last Day of Month

Standard cron doesn't have "last day of month" — but you can script around it:

# Run on the last day of every month (Linux)
0 0 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /path/to/script.sh
Enter fullscreen mode Exit fullscreen mode

In Quartz/Spring, use the L modifier: 0 0 0 L * ?

Every Other Week

Cron can't express "every other week" natively. Workaround: run weekly and check the week number inside your script:

# Every other Monday (even weeks)
0 9 * * 1 [ $(($(date +\%V) \% 2)) -eq 0 ] && /path/to/script.sh
Enter fullscreen mode Exit fullscreen mode

Random Delay (Jitter)

To avoid thundering-herd problems when many servers run the same cron:

# Sleep 0-300 seconds before running
*/5 * * * * sleep $((RANDOM \% 300)) && /path/to/health-check.sh
Enter fullscreen mode Exit fullscreen mode

Cron vs. Alternatives

Tool Best for Limitations
crontab Simple server-side scheduling No retry, no dependency chain, no seconds
systemd timers Modern Linux, with logging and dependencies Linux only, more verbose config
Celery Beat Python app scheduling with workers Requires message broker (Redis/RabbitMQ)
Kubernetes CronJob Containerized workloads 1-minute minimum, cold start latency
AWS EventBridge Serverless scheduling (Lambda, Step Functions) AWS-specific syntax quirks
node-cron In-process Node.js scheduling Dies with the process, no persistence

Build and Test Your Cron Expressions

The fastest way to get a cron expression right is to build it visually. Try DevToolkit's Cron Expression Builder — select your schedule with dropdowns, see the next 5 execution times instantly, and copy the expression. No guessing, no syntax errors.

It supports both standard 5-field and extended 6-field syntax, with human-readable descriptions of what the expression does. Perfect for validating expressions before deploying to production.

Quick Reference Card

Schedule Expression
Every minute `* * * * *`
Every 5 minutes `*/5 * * * *`
Every hour `0 * * * *`
Every day at midnight `0 0 * * *`
Every weekday at 9 AM `0 9 * * 1-5`
Every Monday at 9 AM `0 9 * * 1`
1st of every month `0 0 1 * *`
Every quarter `0 0 1 1,4,7,10 *`
Yearly (Jan 1) `0 0 1 1 *`
Weekdays, business hours `0 9-17 * * 1-5`

Conclusion

Cron expressions are deceptively simple — five fields, a handful of special characters, infinite scheduling power. The key is understanding how fields combine and knowing the quirks of your specific platform (Unix crontab vs. Quartz vs. AWS).

Bookmark this cheat sheet for quick reference. And when you need to build or validate a cron expression, use DevToolkit's visual Cron Expression Builder to get it right the first time.

Top comments (0)