Presets
minute hour day-of-month month day-of-week. Also accepts @daily, @hourly, @weekly and the other macros.
Crontab line:
Next 5 runs
Builder
Crontab syntax in one picture
A classic crontab line has five time fields followed by the command to run:
┌───────────── 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 are Sunday)│ │ │ │ │* * * * * command to runThe daemon wakes up once a minute, compares the current minute, hour, day and month with each line, and starts the command when they match. That makes one minute the smallest interval. The macOS crontab(5) manual page lists the same ranges:
This page covers standard 5-field Unix/Vixie cron, the one you find in /etc/crontab, crontab -e and most Linux distributions. Quartz-style 6/7-field expressions are not supported. Those used by Quartz and Spring add a seconds field and characters like ?, L, W and # that standard cron does not understand.
Special characters
| Character | Meaning | Example | Result |
|---|---|---|---|
* | Every value in the field | * * * * * | Every minute |
, | List of values | 0,30 * * * * | At minute 0 and 30 |
- | Inclusive range | 0 9-17 * * * | Every hour from 9 through 17 |
/ | Step | */15 * * * * | Every 15th minute |
a-b/n | Step inside a range | 10-50/20 * * * * | Minutes 10, 30 and 50 |
a/n | Step from a start value to the end of the field | 5/15 * * * * | Minutes 5, 20, 35 and 50 |
JAN-DEC, SUN-SAT | Names, case-insensitive | 0 0 * JAN MON | Mondays in January (day-of-month is *, so both must match) |
Day-of-week 7 is accepted as Sunday. Ranges are inclusive and must go upward, so 5-1 is invalid; write 5-7,1 if you want to wrap around a week. A step of 0 is invalid, and a step larger than the range only matches the first value. The tool above warns you about that.
Aliases replace the five fields entirely:
| Macro | Same as | Meaning |
|---|---|---|
@yearly, @annually | 0 0 1 1 * | Once a year, midnight on January 1 |
@monthly | 0 0 1 * * | Midnight on the first day of each month |
@weekly | 0 0 * * 0 | Midnight on Sunday |
@daily, @midnight | 0 0 * * * | Every day at 00:00 |
@hourly | 0 * * * * | At minute 0 of every hour |
@reboot | none | Once, when the cron daemon starts |
@reboot has no schedule, so the tool explains it and shows no next runs.
Common cron expressions
Run times below were computed from Friday, October 23, 2026, 10:02:30 UTC. “Next” is the first run after that moment.
| Schedule | Expression | Plain English | Next run (UTC) |
|---|---|---|---|
| Every 5 minutes | */5 * * * * | At every 5th minute. | Oct 23, 10:05 |
| Every hour | 0 * * * * | At minute 0 past every hour. | Oct 23, 11:00 |
| Every day at midnight | 0 0 * * * | At 00:00 every day. | Oct 24, 00:00 |
| Every 6 hours | 0 */6 * * * | At minute 0 past every 6th hour. | Oct 23, 12:00 |
| Twice a day (06:00 and 18:00 ) | 0 6,18 * * * | At 06:00 and 18:00 every day. | Oct 23, 18:00 |
| Weekdays at 9:00 | 0 9 * * 1-5 | At 09:00 on every day-of-week from Monday through Friday. | Oct 26, 09:00 |
| Every Monday at 8:00 | 0 8 * * 1 | At 08:00 on Monday. | Oct 26, 08:00 |
| Every 30 minutes, business hours, weekdays | */30 9-17 * * 1-5 | At every 30th minute past every hour from 9 through 17 on every day-of-week from Monday through Friday. | Oct 23, 10:30 |
| First day of the month | 0 0 1 * * | At 00:00 on day-of-month 1. | Nov 1, 00:00 |
| Every Sunday at midnight | 0 0 * * 0 | At 00:00 on Sunday. | Oct 25, 00:00 |
| Once a year | 0 0 1 1 * | At 00:00 on day-of-month 1 in January. | Jan 1, 2027 |
| 1st and 15th, plus every Friday | 30 4 1,15 * 5 | At 04:30 on day-of-month 1 and 15 or on Friday. | Oct 30, 04:30 |
The */30 9-17 row runs at 17:00
and 17:30
as well, because the hour range includes 17. To stop at 17:00
sharp, use 0,30 9-16 * * 1-5 plus a separate 0 17 * * 1-5.
Cron every 5 minutes
The most searched schedule is */5 * * * *. Read it field by field:
*/5in the minute field is “every 5th value of 0-59”, which is minutes 0, 5, 10, 15 and so on up to 55.- The four stars mean any hour, any day, any month and any weekday.
Starting at 10:02:30 UTC, the tool lists 10:05 , 10:10 , 10:15 , 10:20 and 10:25 . That is 12 runs an hour and 288 a day. The crontab line looks like this (the path is a placeholder):
*/5 * * * * /path/to/script.shThree details that catch people:
- It is not “5 minutes after the last run”. Cron fires on wall-clock minutes. If the script takes 7 minutes, the next copy starts anyway at the next multiple of 5 and you end up with overlapping runs. Guard against that with
flockon Linux or a lock file. - Steps restart every hour.
*/7runs at :00 , :07 , … :56 and then at :00 again, so there is a 4-minute gap at the top of each hour. Only divisors of 60 (2, 3, 4, 5, 6, 10, 12, 15, 20, 30) give an even cadence. - Everyone picks :00
. Many jobs start on the 0 and 5 marks. If load matters, shift with a range step:
3-59/5 * * * *runs at :03 , :08 , :13 and so on through :58 .
The same pattern works for other intervals: */10, */15 and */30 in the minute field, and 0 */2 * * * for every other hour.
The day-of-month and day-of-week gotcha
If both the day-of-month field and the day-of-week field are restricted (neither is *), Vixie cron runs the job when either matches. It does not require both. The manual page says so in its note:
So 0 0 13 * 5 is not “Friday the 13th”. It is “every 13th, and every Friday”. Starting from Friday, October 23, 2026, the next runs are Friday October 30, Friday November 6, the 13th of November, and Friday November 20.
If only one of the two fields is restricted, the other is * and the match is an ordinary AND, so 0 0 13 * * runs only on the 13th. For the Vixie rule, a field that starts with an asterisk counts as unrestricted, so */2 in the day-of-month field still behaves as “every other day” and combines with the weekday by AND.
To get a real “Friday the 13th” you need a guard inside the command, for example:
0 0 13 * * [ "$(date +\%u)" = 5 ] && /path/to/script.shNote the escaped \%, explained below. The builder shows a notice when your expression falls under the OR rule.
Environment gotchas
Most “my cron job does not run” problems are not about the schedule. They are about what cron gives the job.
A minimal PATH. Cron starts commands with a tiny environment. On many Linux systems PATH is only /usr/bin:/bin, and the shell is /bin/sh. The macOS manual says SHELL is /bin/sh and that LOGNAME and HOME come from the passwd entry. Use absolute paths for every command, or set PATH=... at the top of the crontab.
The percent sign. An unescaped % in the command is turned into a newline, and everything after it goes to the command as standard input. Write date +\%F, not date +%F. This is the single most common reason a perfectly good command fails only under cron.
Output and mail. Anything the job prints is mailed to the crontab owner, or to MAILTO if set. MAILTO="" turns mail off. Redirect on purpose:
*/5 * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1Time zone. The schedule is read in the time zone of the machine’s cron daemon, not yours. Check it with date on the server. Servers are often on UTC, so “9:00
” may be a different wall-clock hour than you expect. Some cron implementations support a CRON_TZ variable; the standard Vixie manual page does not document one, so do not rely on it. Daylight saving changes also affect jobs near the shift: the macOS manual warns that jobs scheduled during the rollback or advance will be affected, so avoid 01:00-03:00
in zones that change clocks then.
Execute permission. The script must be executable by the user the job runs as, or cron cannot start it. Run chmod 755 /path/to/script.sh, or use the chmod calculator to pick the right mode. The first line should be a shebang such as #!/usr/bin/env bash.
Comments on the same line. Comments are not allowed after a command. Everything on the line after the five fields is the command, so # note at the end becomes part of it. Put comments on their own line.
Edit, list and test crontab
Each user has a personal crontab. These commands manage it:
crontab -e # edit your crontab in $EDITORcrontab -l # list the installed entriescrontab -r # remove the whole crontab, with no confirmationcrontab -l prints your installed lines, or a message such as “no crontab for user” if you have none. Be careful with -r: it deletes everything at once, and it sits next to -e on the keyboard.
A crontab is a plain text file, which makes it easy to prepare in advance. This file was written in a scratch directory and was not installed:
The date -u line is the point of the exercise. Compare it with your local date before deciding how to write the hour field. When you are ready, crontab mycron would install the file and replace the existing crontab, so run crontab -l first and merge by hand. That step was not run here.
System-wide files such as /etc/crontab and files in /etc/cron.d/ have a sixth column with the user name before the command. Per-user crontabs from crontab -e do not. Do not mix up the two formats.
macOS still ships cron, but its manual page notes that the functionality has been absorbed into launchd, which is Apple’s preferred scheduler.
Logging
Cron does not keep a log of command output on its own, so add redirection as shown above. On many Linux systems the daemon itself logs each job it starts to syslog or the journal: look for lines containing CRON in /var/log/syslog on Debian and Ubuntu, or run journalctl -u cron (the unit is crond on Red Hat family systems). That is GNU/Linux syntax and was not run here. A line there proves cron started the job, not that the job succeeded; the exit status and output are your script’s job.
Common mistakes
- Six fields. Pasting a Quartz or Spring expression such as
0 0 9 * * ?into a crontab. Standard cron has five fields. This tool rejects 6/7-field expressions with a message instead of guessing. - Out-of-range values. Minute 60, hour 24, day 32, month 13 and day-of-week 8 are all invalid. The tool points at the offending field.
- Reversed ranges.
22-3for “late evening to early morning” is rejected. Use22-23,0-3. - Month and day numbering. Months start at 1 and day-of-month at 1, but minutes, hours and weekdays start at 0.
- Name ranges on old systems. The macOS manual page says ranges or lists of names are not allowed, while newer implementations accept
MON-FRI. Use numbers (1-5) if the crontab must run on several systems. - Forgetting the day rule. Setting day-of-month and day-of-week together, expecting AND.
- Assuming interval semantics. Cron matches the clock.
*/45does not mean every 45 minutes. - Editing a file directly. Use
crontab -eso the file is validated and the daemon reloads it.
How the builder works
Each field has four modes: every, every N, specific values and range. Choosing a mode writes the matching syntax (*, */N, 1,15 or 9-17) into the expression box, and typing in the box updates the builder when it can be represented. Fields it cannot show, such as 10-50/10 or 1-5,20, stay as typed and show up as “Custom”. The next runs are calculated from the current time, strictly after now, in your browser’s time zone or UTC.
Parsing, validation, the English text and the run times all happen in your browser. The tool applies the day-of-month/day-of-week rule described above, skips months that do not have the day you ask for (0 0 31 * * skips 30-day months, and 0 0 29 2 * finds the next leap year, February 29, 2028 from this page’s example date), and gives up after about nine years so an impossible schedule such as February 30 returns “never” instead of hanging.
Frequently asked questions
How do I run a cron job every 5 minutes?
Use */5 * * * *. The minute field */5 means every 5th minute starting at 0, so the job runs at :00, :05, :10 and so on through :55, 288 times a day. To shift the schedule by a few minutes use a range with a step, for example 3-59/5 for :03, :08, :13 and so on.
What does * mean in a cron expression?
An asterisk means every possible value of that field: every minute, every hour, every day of the month, every month or every day of the week. * * * * * therefore runs once a minute, which is the finest schedule standard cron supports.
Why did my cron job run on days I did not expect?
Probably because both day-of-month and day-of-week were set. In Vixie-style cron, when neither of those two fields is *, the job runs when either one matches. 0 0 13 * 5 runs on every 13th and on every Friday, not only on Friday the 13th.
Can cron run a job every 90 minutes or every 45 seconds?
Not with one expression. Steps restart at the top of each hour, so */90 only matches minute 0, and cron has no seconds field. For 90 minutes use two or more entries, or let a long-running script or a systemd timer handle the interval. For seconds, run a script every minute that loops and sleeps.
Is 0 or 7 Sunday in cron?
Both. Day-of-week accepts 0 through 7, and 0 and 7 both mean Sunday, so 0 0 * * 0 and 0 0 * * 7 are the same schedule. You can also write SUN through SAT.
Does this tool support Quartz or Spring cron expressions?
No. Quartz-style 6/7-field expressions are not supported. They add a seconds field and special characters such as ?, L, W and #, and they behave differently from the standard 5-field Unix crontab this tool covers.
Which time zone does cron use?
Standard cron uses the time zone of the machine running the daemon, usually the system time zone, which on servers is often UTC. This tool shows the next runs in your browser's time zone and lets you switch to UTC, so you can compare it with the server's date output.
Does this tool send my expression anywhere?
No. Parsing, the description and the run times are all computed in your browser. The expression only appears in the page address when you use the share link, and it stays on your device otherwise.