CCronExplain
Get CronExplain

CronExplain/Guides

Cron Schedule Format Explained: Fields and Examples

Learn the cron schedule format with clear examples. Understand minute, hour, day, month, and weekday fields to write correct expressions.

October 6, 2026 · 5 min read

A cron schedule is a string of five fields that tells a scheduler exactly when to run a task. Each field controls a specific unit of time—minute, hour, day of month, month, and day of week. The job runs when the current time matches the criteria defined in these fields, with the specific rule that if both day-of-month and day-of-week are restricted, the job runs if either matches rather than requiring both to match.

Understanding the Matching Logic

The standard cron expression consists of five space-separated fields. The order is fixed: minute, hour, day of month, month, and day of week. You cannot reorder them. Most systems accept either these five fields or a six-field format where the first field adds seconds precision, but the five-field format is the universal baseline for standard crontabs.

The matching logic has a specific nuance that often causes confusion. For the minute, hour, and month fields, the current time must match the value specified. However, the interaction between the day-of-month and day-of-week fields is different. If both fields are restricted (meaning neither is an asterisk *), the job runs if the current date matches the day-of-month OR the day-of-week. If only one is restricted, that restriction applies. If both are asterisks, any day qualifies. This "OR" logic applies only when both specific fields are set; otherwise, it behaves like a standard AND condition across all fields.

Breaking Down Each Cron Field

Each field accepts specific values and ranges. Understanding what each column controls prevents common scheduling mistakes.

The first field sets the minute. It accepts values from 0 to 59. A single number like 30 runs the job at half past the hour. A step value like */15 runs every 15 minutes.

The second field sets the hour. It accepts values from 0 to 23, using 24-hour clock notation. 9 means 9 AM. 17 means 5 PM.

The third field sets the day of month. It accepts values from 1 to 31. This refers to the calendar date within the month.

The fourth field sets the month. It accepts values from 1 to 12. January is 1, December is 12.

The fifth field sets the day of week. It accepts values from 0 to 7, where both 0 and 7 represent Sunday. Monday is 1, Saturday is 6.

When you want "every" value in a field, you can use an asterisk *. This means "any matching value." For example, * in the hour field means the hour condition is always satisfied.

Common Cron Expression Examples

Consider the expression */15 9-17 * * 1-5. This is a practical schedule for business-hours monitoring. Here is how each field contributes:

*/15    Every 15 minutes (0, 15, 30, 45)
9-17    Between hours 9 and 17 inclusive
*       Any day of the month
*       Any month
1-5     Monday through Friday

This expression fires every quarter-hour during business hours on weekdays. If the current time is Tuesday at 10:03 AM, the next fire times in your local timezone would be:

Tuesday 10:15 AM
Tuesday 10:30 AM
Tuesday 10:45 AM
Tuesday 11:00 AM
Tuesday 11:15 AM
Tuesday 11:30 AM
Tuesday 11:45 AM
Tuesday 12:00 PM
Tuesday 12:15 PM
Tuesday 12:30 PM

Notice that the minute field */15 produces four values per hour: 0, 15, 30, and 45. The hour field 9-17 creates a nine-hour window. The day-of-week field 1-5 excludes weekends. The result is a predictable, repeating pattern that avoids weekend noise.

Another common pattern is 0 * * * *, which runs exactly once per hour at the top of the hour. The 0 in the minute field locks the minute to zero. The * in the hour field means every hour qualifies. This is useful for hourly data aggregation or cache warming.

Handling Special Characters and Ranges

Cron supports several shorthand characters that simplify complex schedules. The asterisk * matches any value in its field. It is the equivalent of saying "always."

The comma , lists specific values. 1,15 in the minute field runs at minute 1 and minute 15. This is useful when you need irregular intervals that do not divide evenly into hours.

The hyphen - defines an inclusive range. 9-17 means hours 9, 10, 11, 12, 13, 14, 15, 16, and 17. Both endpoints are included. Ranges must be ascending; 17-9 is invalid.

The slash / creates a step value. */5 means every 5 units. In the minute field, this produces minutes 0, 5, 10, 15, and so on. You can combine a range with a step: 10-50/5 produces minutes 10, 15, 20, 25, 30, 35, 40, 45, and 50.

These characters can be combined. */10 9-12 * * * runs every ten minutes between 9 AM and noon, every day of the month and every month. The expression is concise but precise. Avoid over-complicating expressions; if a combination becomes hard to read, consider splitting it into multiple jobs.

Verifying Your Schedule with Next-Fire Times

The most reliable way to confirm a cron expression works as intended is to view its next firing times. Mental calculation of cron logic is error-prone, especially with ranges and steps interacting across fields.

Take the expression */15 9-17 * * 1-5 again. A human might assume it runs every 15 minutes from 9 AM to 5 PM. But does it include exactly 5 PM? Does it skip noon? The answer depends on how the scheduler evaluates the hour range boundary.

By computing the next ten actual timestamps, you verify edge cases. If today is Wednesday, you see continuous quarter-hour intervals from 9:00 AM through 5:00 PM. If today is Saturday, the expression produces no fires until Monday. If today is Sunday, the first fire is Monday at 9:00 AM. These behaviors emerge from the interaction of the hour range and weekday range.

CronExplain provides this verification directly. Paste any expression and see the plain-English explanation alongside the next ten firing times in your browser's local timezone. This eliminates guesswork about whether your schedule includes boundary hours or skips intended days. The visual builder lets you adjust each field via dropdowns while watching the resulting expression and fire times update in real time.

Best Practices for Readable Cron Jobs

Write expressions that communicate intent clearly. Prefer explicit values over clever shortcuts when the schedule is simple. 0 9 * * * is more readable than 0 */1 * * * for a daily 9 AM task, even though both work.

Comment your expressions in your configuration file. A short note like # Business hours check every quarter-hour helps future maintainers understand why certain fields were chosen. CronExplain supports saving named schedules with comments, which is useful for teams managing multiple cron jobs across repositories.

Test with realistic timezones. If your server runs in UTC but your team operates in Eastern time, verify that your hour ranges align with your actual working hours. A schedule of 0 9 * * * in UTC fires at 4 AM Eastern, which may not be the intended behavior. Pin your timezone explicitly in your scheduler configuration rather than relying on the system default.

Avoid overlapping schedules. If two jobs both run at the top of the hour, consider staggering them by five minutes to reduce contention. 0 * * * * and 5 * * * * create predictable, non-overlapping execution windows.

Keep expressions within your team's mental model. If everyone understands */15, use it. If your team struggles with step syntax, write out 0,15,30,45 instead. Clarity beats brevity when the cost of misunderstanding is a missed backup or a duplicate email.

Do it in CronExplain

Everything in this guide works in the browser — open the tool and try it on your own input.

Open CronExplain →

Questions people also ask

What is the difference between 5-field and 6-field cron expressions?

Standard cron uses five fields (minute, hour, day, month, weekday), while Quartz-style schedulers use six fields by adding seconds as the first field. Use the five-field format for most Linux and macOS systems, and the six-field format only if your specific scheduler explicitly requires seconds precision.

How do I handle timezones in cron schedules?

Cron expressions themselves do not contain timezone information; they rely entirely on the system clock's configured timezone. To ensure consistency, set the server's system timezone to your desired zone (e.g., UTC or America/New_York) before defining the schedule, as the scheduler interprets the numeric fields relative to that system time.

Why does my cron job not run at the expected minute?

This usually happens because the minute field uses a range or step that does not align with your expectation, such as `*/15` firing at :00, :15, :30, and :45 rather than continuously. Check if your minute field uses a step value like `*/5` which skips intermediate minutes, or verify that the hour range boundaries are inclusive as intended.

Can I use nicknames like @daily instead of numeric fields?

Yes, many modern schedulers support shorthand nicknames like `@hourly`, `@daily`, `@weekly`, and `@monthly` as equivalents to specific numeric patterns. These are convenient for common intervals, but stick to numeric fields for complex logic like specific weekdays or irregular minute steps.

More guides