Guide

The Ultimate Guide to Cron Expressions: Syntax, Examples, and Best Practices

A comprehensive guide to understanding Cron expressions. Learn syntax, special characters, and common examples for scheduling tasks in Linux and development.

In the world of system administration and backend development, Cron is a name you encounter everywhere. It is the time-based job scheduler in Unix-like computer operating systems. Whether it’s backing up databases daily, sending weekly reports, or checking service status every minute, Cron is your most reliable assistant.

The core of configuring Cron jobs lies in writing Cron expressions. For beginners, this string of asterisks, slashes, and numbers might look like cryptic code. This article will guide you through understanding Cron expressions, empowering you to master any scheduling task.

If you need to quickly generate or validate a Cron expression, try our Online Cron Expression Generator, which helps you build correct expressions visually.

1. What is a Cron Expression?

A Cron expression (more precisely, a “Cron-like” schedule expression) is a string made of multiple fields separated by spaces, where each field represents a unit of time. The exact number of fields and supported syntax depends on the implementation: Linux crontab uses 5 fields, while schedulers like Quartz / Spring often include seconds (6 or 7 fields) and support additional special characters. This guide calls out those differences explicitly to avoid copy‑paste surprises.

Standard Linux Crontab uses 5 fields in the following format:

* * * * *
| | | | |
| | | | +----- Day of Week (0 - 7) (Sunday is both 0 and 7)
| | | +------- Month (1 - 12)
| | +--------- Day of Month (1 - 31)
| +----------- Hour (0 - 23)
+------------- Minute (0 - 59)

2. Field Details (Linux Crontab: 5 fields)

FieldAllowed ValuesAllowed Special Characters
Minute0-59* , - /
Hour0-23* , - /
Day of Month1-31* , - /
Month1-12 (some implementations accept JAN-DEC)* , - /
Day of Week0-7 (some implementations accept SUN-SAT)* , - /

Note:

  1. In the “Day of Week” field, both 0 and 7 typically represent Sunday.
  2. Standard Linux Cron does not support second-level scheduling (minimum granularity is one minute). If you need seconds, you usually need to combine it with a loop script or use a more advanced scheduler.
  3. In many Linux Cron implementations, if both “Day of Month” and “Day of Week” are restricted (not *), the match is typically an OR (either one matches triggers the job), not an AND. To avoid surprises, prefer restricting only one of those fields and keeping the other as *.

3. Field Details (Quartz / Spring extensions: includes seconds)

In Quartz (and other Cron-like schedulers), the expression is commonly 6 or 7 fields (including seconds). The format is:

Seconds  Minutes  Hours  Day of Month  Month  Day of Week  Year (Optional)
   |        |       |        |           |         |             |
   0-59    0-59    0-23     1-31        1-12      1-7         1970-2099

Critical Difference: Day of Week

  • Linux Crontab: 0-7 (0 and 7 are Sunday)
  • Quartz: 1-7 (1 is Sunday, 2 is Monday, etc.) Always verify which standard your system uses!

These expressions support additional special characters such as ?, L, W, and #, and are not fully compatible with Linux crontab.

4. Special Characters Explained

4.1 Common special characters (Linux Cron)

  • * (Asterisk): Represents “every”. For example, * in the Minute field means “every minute”.
  • , (Comma): Represents “enumeration”. For example, 5,10,15 means execute at the 5th, 10th, and 15th minute.
  • - (Hyphen): Represents a “range”. For example, 10-12 means execute at 10, 11, and 12 o’clock.
  • / (Slash): Represents “step” (interval). For example, */5 means execute every 5 units. In the Minute field, */5 means every 5 minutes.

4.2 Common special characters (Quartz and similar schedulers)

  • ? (Question Mark): Used in “Day of Month” and “Day of Week” to mean “no specific value”. When one of those fields is specified, the other is often set to ? to avoid conflicts.
  • L (Last): Means “last”. In “Day of Month” it can mean the last day of the month; in “Day of Week” it can mean the last occurrence of a weekday (exact semantics vary by implementation).
  • W (Weekday): Typically used in “Day of Month” to mean the nearest weekday to a given day.
  • #: Used in “Day of Week” to mean the nth occurrence of a weekday in the month (check your scheduler’s docs). For example, 2#1 commonly means “the first Monday of the month”.

5. Common Cron Expression Examples

5.1 Linux Crontab (5 fields)

ExpressionMeaning
* * * * *Execute every minute
0 * * * *Execute at minute 0 of every hour (i.e., hourly)
0 0 * * *Execute at 00:00 every day (midnight)
0 0 * * 0Execute at 00:00 every Sunday
0 0 1 * *Execute at 00:00 on the 1st day of every month
*/10 * * * *Execute every 10 minutes
0 9-18 * * *Execute hourly between 9 AM and 6 PM
0 9,12,18 * * *Execute at 9 AM, 12 PM, and 6 PM sharp
0 0 * * 1-5Execute at 00:00 every weekday (Monday to Friday)
0 0 * * 6,0Execute at 00:00 every weekend (Saturday and Sunday)

5.2 Quartz (6 fields, includes seconds)

ExpressionMeaning
0 * * * * ?Execute every minute (at second 0)
0 0 * * * ?Execute hourly, on the hour
0 0 0 * * ?Execute daily at 00:00:00
0 30 23 L * ?Execute at 23:30:00 on the last day of the month
0 0 12 ? * MON-FRIExecute at 12:00:00 every weekday

6. Advanced Tips and Best Practices

6.1 Environment Variables

Cron jobs run with a minimal set of environment variables (often only HOME, LOGNAME, SHELL, and limited PATH). Therefore, it’s best to use absolute paths for commands and files in your scripts, or explicitly set the PATH at the beginning of your script.

6.2 Output Redirection

The output (stdout and stderr) of a Cron job is typically mailed to the user. If you don’t want to receive emails, or if you want to save logs to a file, be sure to use redirection:

# Redirect both stdout and stderr to /dev/null (discard)
0 * * * * /path/to/script.sh > /dev/null 2>&1

# Append logs to a file
0 * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1

6.3 Avoiding “Thundering Herd”

If you have a large number of scheduled tasks running at 0 0 * * * (midnight), it can cause a sudden spike in system load. It is recommended to stagger execution times, for example:

  • Job A: 3 0 * * *
  • Job B: 17 0 * * *

6.4 Day-of-month vs day-of-week matching (Linux)

Many people assume “Day of Month” and “Day of Week” must both match, but in common Linux Cron implementations, restricting both fields usually results in an OR match (either field matching triggers the job). To keep schedules predictable:

  • Restrict only one of those fields
  • Keep the other as *

6.5 Time zones and daylight saving time (DST)

Cron usually runs in the system time zone. On DST transition days, some local times may be skipped or repeated, causing a job to run one fewer or one extra time. For critical schedules, use a scheduler that supports explicit time zones, and make jobs idempotent with deduplication logic.

6.6 Predefined macros (supported by some Linux Cron implementations)

Some implementations support more readable directives such as:

  • @reboot: run at system startup
  • @hourly / @daily / @weekly / @monthly / @yearly: run at fixed intervals

6.7 Different Cron Implementations

  • System Cron: Native to Linux, configuration usually in /etc/crontab or /var/spool/cron/.
  • Quartz / Spring Schedule: Common in Java development, supports second-level precision (6 or 7 fields).
  • Node-cron: Cron implementation for Node.js.

Different implementations vary in their support for special characters (like L, W, #, ?), so always refer to the specific documentation.

7. Conclusion

Mastering Cron expressions is a fundamental skill for every developer. Although the syntax is simple, the combinations are endless.

To avoid manual calculation errors, we strongly recommend using tools for verification before deployment. Don’t forget to bookmark our Online Cron Expression Generator to make scheduling tasks simple and efficient.