Cron field reference
| * | Any value (every minute, every hour, etc.) |
| 5 | A specific value (e.g. minute 5) |
| 1-5 | A range (e.g. Monday through Friday) |
| 1,3,5 | A list of specific values |
| */15 | A step (every 15 units) |
| 0-30/5 | A step within a range (every 5 from 0 to 30) |
This free cron expression builder turns a cron schedule into plain English and shows you exactly when it will run next, all in your browser. Type or build an expression and you immediately see a readable translation (“at 9:00 AM, Monday through Friday”) plus the next several scheduled run times in your local time. Presets cover the common schedules, and a field reference is built in. Below the tool is a complete guide to cron syntax: what each field means, how to read and write expressions, the special characters, the gotchas that trip people up, and ready-to-use examples.
What is a cron expression?
A cron expression is a compact string that defines a repeating schedule. It tells a system when to run a task automatically, such as “every night at midnight” or “every 15 minutes” or “at 9 AM on weekdays.” Cron is the time-based job scheduler built into Unix and Linux systems, and its expression format has become the near-universal language for scheduling, used far beyond Unix itself in cloud platforms, CI pipelines, container orchestrators, and countless application frameworks.
The reason cron expressions are worth understanding is that they appear everywhere a recurring task needs to be defined, and the syntax, while terse, is the same across most of those systems. Learning to read and write it once means you can schedule jobs almost anywhere. The catch is that the syntax is famously easy to forget, which is exactly why a builder that translates it back into plain English and previews the run times is so useful, and why developers keep one bookmarked.
The five fields
A standard cron expression has five fields separated by spaces, each controlling one unit of time. Read left to right, they are minute, hour, day of the month, month, and day of the week.
| Position | Field | Allowed values |
|---|---|---|
| 1 | Minute | 0 to 59 |
| 2 | Hour | 0 to 23 (24-hour clock) |
| 3 | Day of month | 1 to 31 |
| 4 | Month | 1 to 12 (or JAN to DEC) |
| 5 | Day of week | 0 to 6 (0 = Sunday, or SUN to SAT) |
So the expression 0 9 * * 1-5 reads field by field as: minute 0, hour 9, any day of the month, any month, on days of the week 1 through 5 (Monday through Friday). Put together, that is “at 9:00 AM, Monday through Friday.” The builder above shows this translation live as you edit each field, which is the fastest way to confirm an expression does what you intend.
The special characters
Each field can hold more than a single number. A small set of special characters lets you express ranges, lists, and repetition, and they are the same in every field.
The asterisk (*)
An asterisk means “every value” for that field. In the minute field it means every minute; in the hour field, every hour. The expression * * * * *, all asterisks, therefore means “every minute of every hour of every day,” the most frequent schedule cron allows.
The comma (,)
A comma creates a list of specific values. In the day-of-week field, 1,3,5 means Monday, Wednesday, and Friday. In the hour field, 9,12,17 means at 9 AM, noon, and 5 PM. Lists let you pick exact moments that are not evenly spaced.
The hyphen (-)
A hyphen defines a range. In the day-of-week field, 1-5 means Monday through Friday. In the hour field, 9-17 means every hour from 9 AM to 5 PM. Ranges are inclusive of both ends.
The slash (/)
A slash defines a step, meaning “every nth value.” In the minute field, */15 means every 15 minutes (at 0, 15, 30, and 45). You can combine it with a range, so 0-30/10 in the minute field means every 10 minutes from 0 to 30. The slash is the source of most “every N minutes/hours” schedules.
*/15 in the minute field does NOT mean “15 minutes after the job last ran.” Cron has no memory of previous runs. It means “at minutes 0, 15, 30, 45 of every hour”, fixed clock positions, not intervals measured from a start time.Reading an expression step by step
Let us decode a less obvious example: 30 2 * * 0. Taking it field by field: minute 30, hour 2, any day of the month, any month, day of week 0. Day 0 is Sunday. So this runs at 2:30 AM every Sunday, a classic schedule for a weekly maintenance task placed in the quiet early hours. The builder above would show exactly this translation and list the next few Sunday mornings it will fire, so you never have to decode it in your head.
Now a trickier one: 0 */6 * * *. Minute 0, hour every 6, every day. “Hour every 6” means hours 0, 6, 12, and 18, so this runs four times a day at midnight, 6 AM, noon, and 6 PM, always on the hour. The step in the hour field is what turns a daily job into a four-times-daily one.
The day-of-month and day-of-week gotcha
This is the single most confusing part of cron, and it trips up even experienced developers. When you specify BOTH the day-of-month field and the day-of-week field (that is, neither is an asterisk), cron runs the job when EITHER condition is met, not both. They combine with OR, not AND.
So 0 0 13 * 5 does not mean “midnight on Friday the 13th.” It means “midnight on the 13th of every month, AND also midnight on every Friday”, two separate triggers. If you actually want Friday the 13th only, cron cannot express that cleanly in the standard syntax, and you typically handle the extra condition in your job’s own code. Knowing this OR behavior prevents schedules that fire far more often than intended, which is why the builder above previews the real run times: if you see it firing on days you did not expect, this rule is usually why.
Named values and shortcuts
For readability, the month and day-of-week fields accept three-letter names instead of numbers. You can write JAN through DEC for months and SUN through SAT for weekdays, so 0 9 * * MON is the same as 0 9 * * 1. Many cron implementations also support shorthand macros that replace the whole expression, such as @daily (equivalent to 0 0 * * *), @hourly, @weekly, @monthly, and @reboot (run once at startup). Support for these macros varies between systems, so the five-field form is the most portable and is what this builder works with.
Common cron expressions to copy
Here are schedules you will reach for often, ready to adapt. Try any of them in the builder above to see the translation and next runs.
| Expression | Meaning |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
0 * * * * | Every hour, on the hour |
0 0 * * * | Every day at midnight |
0 9 * * 1-5 | 9 AM on weekdays |
0 0 * * 0 | Midnight every Sunday |
0 0 1 * * | Midnight on the 1st of each month |
30 2 * * * | 2:30 AM every day |
0 0 1 1 * | Midnight on January 1st (yearly) |
Where cron expressions are used
Beyond traditional Unix crontab files, the same five-field syntax shows up across modern infrastructure. Cloud scheduler services use it to trigger functions. Container orchestrators use it to run scheduled jobs. CI and automation platforms use it to kick off pipelines on a timetable. Application frameworks use it for background tasks. The wide reuse is precisely why the format is worth learning once: the schedule you build and verify here will, with only minor differences, work in most of those systems. When a job involves timestamps, the Unix timestamp converter pairs naturally with cron for reasoning about exact run moments.
How to use this cron builder
Type a cron expression into the field at the top, or click a preset to load a common one. The plain-English translation updates instantly, and the list below shows the next several times the schedule will fire, in your local time, so you can confirm the behavior at a glance rather than decoding the syntax in your head. The field map under the input reminds you what each of the five positions controls and its allowed range. If you enter something invalid, the tool tells you what is wrong. The Copy button grabs the expression for pasting into your crontab or scheduler. Everything runs locally in your browser, so nothing you build is sent anywhere.
Timezones: the caveat that causes missed jobs
A cron schedule has no timezone of its own; it runs according to the clock of the system it is on. This is a frequent source of confusion when a job seems to fire an hour early or late. If your server runs in UTC but you were thinking in your local time, a schedule of 0 9 * * * fires at 9 AM UTC, which may be the middle of the night where you are. The run-time preview in the builder above shows times in your browser’s local timezone to help you reason about this, but always confirm what timezone your actual scheduler uses.
Daylight saving time adds a further wrinkle. On the day clocks shift, a daily job scheduled during the skipped or repeated hour may run twice or not at all, depending on the system. For jobs where exact timing matters, many teams set their servers to UTC specifically to avoid daylight saving surprises, scheduling in a timezone that never shifts and converting to local understanding only when reading the schedule. If you are reasoning about specific moments, the Unix timestamp converter helps translate between the absolute time a job runs and a readable local date.
Cron across different platforms
The five-field syntax is widely shared, but implementations differ in small ways worth knowing before you copy an expression between systems. Traditional Unix and Linux crontab uses exactly the five fields described here. Some schedulers add a sixth field at the front for seconds, so an expression that works in one place may be misread in another that expects the seconds field, shifting every value one position to the left. Other systems add non-standard characters such as L for “last”, W for “nearest weekday”, or # for “nth weekday of the month”, which the standard five-field format does not support.
The practical rule is to know which dialect your target expects. The plain five-field form covered here and supported by this builder is the most portable and the safest default. When you move an expression into a specific cloud scheduler, CI platform, or framework, check its documentation for whether it adds a seconds field or extra characters, and adjust accordingly. An expression that previews correctly here will behave the same in any standard five-field scheduler, which covers the large majority of cases.
Why a cron job did not run: a debugging checklist
When a scheduled job fails to fire, the cause is usually mundane, and checking a short list resolves most cases. First, confirm the expression actually matches when you think it does by pasting it into the builder above and reading the next run times; a surprising number of “it did not run” reports are simply schedules that do not mean what their author assumed, often because of the day-of-month and day-of-week OR behavior described earlier.
Second, check the timezone of the system, since a job that “did not run” at the expected local time may have run correctly in the server’s own timezone. Third, verify the job itself works when run manually, because cron firing on schedule but the task erroring out looks identical to cron not firing if you are only watching for results. Fourth, on traditional crontab systems, confirm the crontab is actually installed and that the user it runs as has the permissions and environment the job needs, as cron runs with a minimal environment that often lacks variables present in an interactive shell.
Working through that list, schedule meaning, timezone, the task itself, and the environment, accounts for the overwhelming majority of cron problems. The builder above directly addresses the first and most common one by making the real schedule visible, so you can rule out a misunderstood expression in seconds before digging into the rest.
Building a schedule from a plain requirement
Most of the time you start not with an expression but with a requirement in words, and the skill is translating it into the five fields. Work through it one field at a time, from the smallest unit up. Suppose the requirement is “run a report every weekday at 6:30 in the evening.” Start with the minute: 30. Then the hour: 6:30 PM is 18:30 on a 24-hour clock, so the hour is 18. The day of the month does not matter, so it stays an asterisk. The month does not matter, another asterisk. The day of the week is weekdays, Monday through Friday, which is 1-5. Assembling left to right gives 30 18 * * 1-5. Paste that into the builder above and it confirms “at 6:30 PM, Monday through Friday.”
Take a second requirement: “back up the database every six hours.” The backup should run on the hour, so the minute is 0. Every six hours is a step in the hour field, */6, which fires at 0, 6, 12, and 18. The remaining three fields do not matter, so they are asterisks. The result is 0 */6 * * *. This field-by-field method, deciding each position from the requirement and defaulting to an asterisk whenever a unit does not matter, turns even unfamiliar schedules into a quick, mechanical translation, and the live preview lets you confirm it immediately rather than waiting for the job to run or not run.
The reverse skill, reading an unfamiliar expression, uses the same approach in the other direction: take each field in turn, translate it, and assemble the meaning. With practice the common shapes become recognizable at a glance, but until then, a builder that does the translation for you removes the guesswork entirely, which is exactly why keeping one handy is worthwhile even for experienced developers.
When cron is and is not the right tool
Cron is excellent for fixed, recurring schedules: nightly backups, hourly syncs, weekly reports, anything that should happen at known clock times. It is simple, reliable, and universally understood. But it has limits worth recognizing so you reach for the right tool. Cron has no concept of a job’s previous run, so it cannot natively express “every six hours measured from when the last run finished”; it only fires at fixed clock positions. It also has no built-in retry, alerting, or dependency handling, so if a run fails, cron simply waits for the next scheduled time.
For schedules driven by intervals rather than clock times, or for workflows where one job must wait for another to finish, where failures must trigger retries or alerts, or where you need visibility into run history, a dedicated job scheduler or workflow orchestrator is a better fit than raw cron. Many such systems still accept cron syntax for the timing portion, so the skill of reading and writing expressions remains useful even when the scheduler around it is more sophisticated. The decision is not cron versus everything else, but recognizing when a plain recurring schedule is enough, which is often, and when the job’s needs have outgrown what a single expression can describe.
For the common case, though, a correct cron expression is all you need, and the main risk is simply getting the syntax wrong or misunderstanding what it will do. That is the precise problem the builder above solves: it removes the ambiguity by showing the schedule in plain English and previewing exactly when it will fire, so you can commit an expression to your scheduler with confidence rather than hope.
Frequently asked questions
What are the five fields in a cron expression?
In order: minute (0 to 59), hour (0 to 23), day of the month (1 to 31), month (1 to 12), and day of the week (0 to 6, where 0 is Sunday). Each field can use special characters for ranges, lists, and steps.
What does */5 mean in cron?
It is a step value meaning “every 5.” In the minute field, */5 means at minutes 0, 5, 10, 15 and so on, every 5 minutes. It refers to fixed clock positions, not an interval since the last run.
How do I run a cron job every day at a specific time?
Set the minute and hour and leave the rest as asterisks. For 9:30 AM daily, use 30 9 * * *. The builder above shows the translation and next runs so you can confirm it.
Why does my cron job run more often than expected?
Usually the day-of-month and day-of-week gotcha. If both fields are set, cron runs when EITHER matches, not both. Set one of them to an asterisk unless you genuinely want the OR behavior.
Can a cron expression run on the last day of the month?
Standard five-field cron cannot express “last day of month” directly. Some extended cron dialects add an L character for this, but for portability most people handle it in the job’s own logic.
Is anything I type here sent to a server?
No. The expression is parsed and the run times are calculated entirely in your browser. Nothing is uploaded, logged, or stored.

