Cron Expression Cheat Sheet & Examples

DevToolkit Team · · 14 min read

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 (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌───────────── day of month (1–31)
│ │ │ ┌───────────── month (1–12 or JAN–DEC)
│ │ │ │ ┌───────────── day of week (0–7 or SUN–SAT, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *

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

CharacterMeaningExample
*Any value* * * * * — every minute
,List separator0 8,12,18 * * * — at 8am, noon, 6pm
-Range0 9-17 * * * — every hour from 9am to 5pm
/Step*/15 * * * * — every 15 minutes
LLast (non-standard)0 0 L * * — last day of month
WNearest 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)

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

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

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

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)

Extended 6-Field Syntax (Seconds)

Some systems (Quartz, Spring, AWS EventBridge) 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)
│ │ │ │ │ │
* * * * * *
*/30 * * * * *    # Every 30 seconds
0 */5 * * * *     # Every 5 minutes (at second 0)
0 0 * * * *       # Every hour (at second 0, minute 0)

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

Key crontab tips:

GitHub Actions

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

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

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)

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:

  1. Timezone confusion. Crontab runs in the system's local timezone. GitHub Actions and AWS use UTC. Always document which timezone your cron uses.
  2. 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.
  3. February 30th. 0 0 30 2 * will never fire. Cron silently skips impossible dates.
  4. 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.
  5. 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

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

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

Cron vs. Alternatives

ToolBest forLimitations
crontabSimple server-side schedulingNo retry, no dependency chain, no seconds
systemd timersModern Linux, with logging and dependenciesLinux only, more verbose config
Celery BeatPython app scheduling with workersRequires message broker (Redis/RabbitMQ)
Kubernetes CronJobContainerized workloads1-minute minimum, cold start latency
AWS EventBridgeServerless scheduling (Lambda, Step Functions)AWS-specific syntax quirks
node-cronIn-process Node.js schedulingDies 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

ScheduleExpression
Every minute* * * * *
Every 5 minutes*/5 * * * *
Every hour0 * * * *
Every day at midnight0 0 * * *
Every weekday at 9 AM0 9 * * 1-5
Every Monday at 9 AM0 9 * * 1
1st of every month0 0 1 * *
Every quarter0 0 1 1,4,7,10 *
Yearly (Jan 1)0 0 1 1 *
Weekdays, business hours0 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.

Enjoyed this article?

Get the free Developer Cheatsheet Pack + weekly tips on tools, workflows, and productivity.

Subscribe Free

Try These Tools

Related free tools mentioned in this article

Back to Blog