Cron Expression Parser
Enter a 5-field cron expression to get a plain-English explanation and per-field breakdown.
Related Tools
Frequently Asked Questions
What is a cron expression?
A cron expression is a string of 5 or 6 fields defining when a scheduled task runs: minute, hour, day of month, month, day of week (and optionally seconds). For example, "0 9 * * 1-5" means 9:00 AM every weekday.
What do * and ? mean in cron?
* means "every value for this field." For example, * in the hour field means every hour. ? means "no specific value" and is used in day-of-month or day-of-week when the other is already specified.
How do I run something every 15 minutes?
Use */15 in the minute field: "*/15 * * * *". The */ syntax means "every N units." Similarly, */2 in the hour field runs every 2 hours.
Mastering Cron Expressions: A Developer's Complete Reference
Cron is one of the oldest and most ubiquitous scheduling utilities in the Unix ecosystem, and its expression syntax has become the de facto standard for defining recurring tasks across modern infrastructure. From classic Unix cron daemons to Kubernetes CronJobs, AWS CloudWatch Events, GitHub Actions schedules, and Node.js libraries like node-cron, the five-field cron expression is everywhere. Yet its compact syntax can be opaque without a reference, making a cron parser an indispensable tool for anyone managing scheduled automation.
Anatomy of a Cron Expression
A standard cron expression consists of five fields separated by spaces, representing minute, hour, day of month, month, and day of week — in that order. The expression 30 9 * * 1-5 means "at 9:30 AM, every day from Monday through Friday." Each field can contain a specific value, a wildcard asterisk meaning "every valid value," a range using a hyphen, a list using commas, or a step value using a forward slash. Some implementations add a sixth field for seconds at the beginning, while others add a seventh for year at the end.
The valid ranges for each field are: minutes 0–59, hours 0–23, day of month 1–31, month 1–12 (or JAN–DEC), and day of week 0–7 where both 0 and 7 represent Sunday (or SUN–SAT for named days). Month and day names are case-insensitive in most implementations. When both day-of-month and day-of-week are specified, many cron implementations treat them as an OR condition — the job runs when either condition is true — though this varies between implementations.
Special Characters and Shortcuts
The asterisk (*) wildcard is the most common cron character, representing every possible value in a field. A step value like */15 in the minutes field means "every 15 minutes" — it divides the range by the step value. The expression */15 * * * * runs at 0, 15, 30, and 45 minutes past each hour. Ranges combined with steps are powerful: 0-30/5 in the minutes field runs at 0, 5, 10, 15, 20, 25, and 30 minutes past the hour, stopping before 30 is passed.
Many cron implementations support special strings that replace the five-field expression for common schedules: @yearly (0 0 1 1 *), @monthly (0 0 1 * *), @weekly (0 0 * * 0), @daily (0 0 * * *), and @hourly (0 * * * *). Some also support @reboot to run a job once when the cron daemon starts. These shortcuts improve readability significantly and should be used when available, since they communicate intent immediately without requiring the reader to parse all five fields.
Common Cron Expression Patterns
A few patterns appear repeatedly in real-world cron usage. Running a database backup every night at 2 AM: 0 2 * * *. Sending a weekly digest email every Monday at 8 AM: 0 8 * * 1. Running a cleanup job every 30 minutes during business hours: */30 9-17 * * 1-5. Generating a monthly report on the first of each month at midnight: 0 0 1 * *. Rotating log files every hour: 0 * * * *. Recognizing these patterns quickly makes reading and writing cron schedules much faster.
One common source of confusion is the difference between day-of-month and day-of-week constraints. The expression 0 0 1 * 1 does not mean "the first Monday of each month" — it means "midnight on the 1st of each month OR midnight on any Monday." To schedule a task for the first Monday of the month, you need more sophisticated logic than a standard cron expression can provide, either by using a more feature-rich scheduler or by adding conditional logic in the script itself.
Cron in Modern Cloud and DevOps Environments
While the classic Unix cron daemon is still widely used on Linux servers, cron expression syntax has been adopted by virtually every modern scheduling system. AWS EventBridge (formerly CloudWatch Events) uses cron expressions to trigger Lambda functions, Step Functions, and other services on a schedule. Kubernetes CronJobs define their schedule using the same five-field format. GitHub Actions workflows support a schedule trigger using cron syntax for running CI pipelines at regular intervals. Terraform's aws_cloudwatch_event_rule resource accepts cron expressions directly.
Cloud environments sometimes add variations. AWS uses a slightly different syntax where ? is used in place of * for the day-of-month or day-of-week field when the other is specified, to make the OR behavior explicit. Azure Logic Apps and Google Cloud Scheduler both support extended cron with seconds. When working across multiple platforms, always verify which cron dialect a given system uses, since subtle differences in how wildcards and ranges interact can cause a schedule to fire at unexpected times.
Timezone Considerations in Scheduled Jobs
One of the most common sources of bugs in scheduled tasks is timezone handling. By default, cron runs jobs according to the local timezone of the machine or the UTC timezone of the server. Cloud functions and container-based jobs often run in UTC, which means a cron expression written to fire "at 9 AM" might actually fire at 9 AM UTC — which is 5 AM Eastern, 2 AM Pacific, or 10 AM CET, depending on the season and the user's location. This can cause scheduled reports to arrive at the wrong time, or overnight jobs to run during business hours.
Always document the timezone assumption in any cron expression you write, and prefer UTC when possible to avoid daylight saving time complications. Many modern schedulers support an explicit timezone field — for example, in GitHub Actions you can pair a cron schedule with environment variables that set context, while Kubernetes CronJobs added a timeZone field in version 1.27. When the scheduler does not support timezone-aware scheduling natively, adjust your cron expression manually to account for the UTC offset of your target timezone, remembering that the offset changes twice a year in regions that observe daylight saving time.
Testing and Debugging Cron Schedules
Before deploying a cron job to production, always use a parser to verify that your expression fires at the times you expect, especially for complex schedules combining ranges, steps, and specific values. Generate the next 10 or 20 scheduled fire times and check that they match your intent. Pay special attention to edge cases: does your monthly job correctly handle February? Does a schedule that runs "on the 30th" skip February and handle 31-day months appropriately? A parser that shows upcoming execution times gives you concrete evidence that the schedule is correct before any code runs.
For production jobs, always implement logging and alerting so you know when a job ran and whether it succeeded. Missed executions — jobs that should have run but didn't due to server downtime, resource exhaustion, or a misconfigured schedule — are a silent failure mode that can go undetected for days. Tools like Healthchecks.io, Cronitor, and Dead Man's Snitch provide heartbeat monitoring specifically designed for scheduled jobs, alerting you when an expected execution doesn't occur on time. Combining a well-tested cron expression with execution monitoring gives you reliable, observable scheduled automation.