Cron every 90 minutes: the two line crontab that works
No single cron expression fires every 90 minutes, because the interval is longer than the minute field and not a whole number of hours. Two lines that step the hour by 3 do it exactly.
At a glance
- Expression
- 0 */3 * * * plus 30 1-23/3 * * *
- Fires
- 16 times a day, once every 90 minutes, with the pattern repeating every 3 hours.
- Restricted fields
- Minute and hour on both lines. Date fields stay open.
- Equivalent macro
- None.
- Run times
- 00:00, 01:30, 03:00, 04:30, 06:00, 07:30, 09:00, 10:30 and so on.
- Why two lines
- The cycle contains one run on the hour and one on the half hour, and no single field can express both.
In detail
Ninety minutes is an hour and a half, so any expression that pins a single minute value is wrong half the time. The runs alternate between the top of the hour and half past, and cron has no way to say that in one line because the minute and hour fields are matched independently rather than as a joint cycle.
The fix is to notice that 90 minutes and 3 hours share a period. Two runs fit exactly into every three hour block, one at the start and one 90 minutes in. So one line fires at minute 0 of hours 0, 3, 6, 9, 12, 15, 18 and 21, and a second fires at minute 30 of hours 1, 4, 7, 10, 13, 16, 19 and 22. Eight plus eight is sixteen runs a day, which is 1,440 divided by 90.
Both lines have to run the same command, which means the command has to be safe to invoke from two places. That is normally fine, but it does mean a change to the script path has to be made twice, and a comment above the pair saving the reader the arithmetic is worth the two seconds it takes to write.
Some people reach for a sleep instead: schedule hourly and sleep 30 minutes on alternate runs. Do not. The sleeping process holds a cron slot open, it does not survive a reboot in the state you expect, and after a daemon restart the alternation loses its phase with nothing to resynchronise it.
Examples
0 */3 * * * /opt/app/bin/job.sh >> /var/log/job.log 2>&1
30 1-23/3 * * * /opt/app/bin/job.sh >> /var/log/job.log 2>&10 */3 * * *
30 1-23/3 * * *Paste one line at a time. The next run list makes the interleaving obvious.
15 */3 * * * /opt/app/bin/job.sh
45 1-23/3 * * * /opt/app/bin/job.shSame 90 minute spacing, first run of the day at 00:15.
Things that catch people out
- 1-23/3 is not the same as */3. It starts the walk at hour 1, giving 1, 4, 7 and so on, which is precisely the offset the second line needs.
- Writing 90 anywhere in the minute field is a range error. The field stops at 59.
- The two lines drift apart the moment someone edits one of them. Keep them adjacent and comment the intent.
Try it: Cron Expression Parser
Paste any five or six field expression to get a plain English description, a per field breakdown and the next run times in your local time.
Cron Expression Parser
LOCAL · Browser-OnlyParse cron expressions and see the next scheduled run times
Supports 5-field (minute hour day month weekday), 6-field (with seconds), named values (JAN, MON), and @macros (@daily, @hourly, ...)
Use the dropdowns below to build your cron expression visually, or type a custom value in each field.
Human-Readable Description
Every 5 minutes
Field Breakdown
| Field | Allowed | Value | Meaning |
|---|---|---|---|
| Minute | 0-59 | */5 | every 5 minute(s) |
| Hour | 0-23 | * | every hour |
| Day of Month | 1-31 | * | every day of month |
| Month | 1-12 | * | every month |
| Day of Week | 0-7 | * | every day of week |
Related cron expressions
All cron expressions →Cron every 45 minutes: why */45 * * * * does not do it
*/45 * * * * fires at minute 0 and minute 45 only, so the gaps alternate 45 and 15 minutes. Here is the four line crontab that really runs every 45 minutes.
Cron every 3 hours: 0 */3 * * *
0 */3 * * * fires eight times a day at 00:00, 03:00, 06:00 and on to 21:00. Three divides 24 exactly, so the midnight gap is the same as the rest.
Cron n/step: starting a step from a value you choose
The form 5/15 means start at 5 and step by 15, giving 5, 20, 35 and 50. It is how you move a repeating job off the crowded top of the hour.
The cron hour field: 0 to 23 on a 24 hour clock
The hour field runs 0 to 23 on a 24 hour clock. Midnight is 0, noon is 12, and 24 is out of range. There is no AM or PM notation.
Cron every second: * * * * * * with a seconds field
Six asterisks means every second, 86,400 times a day. Standard crontab has no seconds field, so this form only works in schedulers that accept six.
Cron every 10 seconds: */10 * * * * * and the alternative
*/10 * * * * * fires 8,640 times a day at seconds 0, 10, 20, 30, 40 and 50. What to do when the scheduler only accepts five fields.
Tools for this
- Cron Expression Parser Free online cron expression parser - parse cron expressions and see the next scheduled run times
- Crontab Generator Free online crontab generator - build cron expressions visually with an intuitive interface