Cron every 45 minutes: why */45 * * * * does not do it
*/45 * * * * does not fire every 45 minutes. It fires at minute 0 and minute 45 of every hour, so the gaps alternate between 45 minutes and 15 minutes.
At a glance
- Expression
- */45 * * * *
- Fires
- 48 times a day for */45. A genuine 45 minute cycle fires 32 times a day.
- Restricted fields
- Minute only, and only two values in it: 0 and 45.
- Equivalent macro
- None, and no macro exists for any interval that does not divide an hour or a day.
- What */45 actually matches
- Minute 0 and minute 45. The walk 0, 45, 90 stops because 90 is past 59.
- Gap pattern
- 45 minutes, then 15 minutes, repeating.
- True 45 minute cycle
- Repeats every 3 hours: 00:00, 00:45, 01:30, 02:15, then 03:00.
In detail
Every step expression is evaluated inside one field, and the minute field ends at 59. Starting at 0 and stepping by 45 gives 0 and 45, and the next candidate, 90, does not exist. So */45 produces two runs an hour with a long gap and a short gap, which is not what anyone means when they say every 45 minutes.
A real 45 minute cycle does not fit in the minute field at all, because 45 does not divide 60. The pattern only repeats once the offsets come back into phase, which happens after three hours: 00:00, 00:45, 01:30, 02:15, and then 03:00 starts the cycle again. Four runs every three hours is 32 runs a day.
Expressing that takes four crontab lines, one for each position in the three hour cycle. Each line pins a minute and steps the hour field by 3 from a different starting hour. It looks verbose, but it is exact, and it survives a reboot in a way that a script sleeping in a loop does not.
If the exact spacing does not matter and you only wanted something between half hourly and hourly, take the hint and pick a divisor of 60. Every 30 minutes or every 20 minutes gives an even cadence in one readable line, and nobody maintaining the crontab in a year has to work out what the four line block was for.
Examples
*/45 * * * *Runs at :00 and :45. Gap of 45 minutes, then a gap of 15.
0 */3 * * * /opt/app/bin/job.sh
45 0-23/3 * * * /opt/app/bin/job.sh
30 1-23/3 * * * /opt/app/bin/job.sh
15 2-23/3 * * * /opt/app/bin/job.shFires at 00:00, 00:45, 01:30, 02:15, 03:00 and so on. 32 runs a day, evenly spaced.
*/30 * * * *48 runs a day, one line, even spacing.
Things that catch people out
- The expression is valid, so nothing warns you. Reading the run times is the only way to notice that the interval alternates.
- The four line version runs the same command from four crontab entries. If the job is not safe to run twice, a lock file is still needed, because a slow run at 02:15 can still be going at 03:00.
- Any interval that does not divide 60 or 1,440 has this problem. 25 minutes, 40 minutes and 7 hours all fail the same way.
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 90 minutes: the two line crontab that works
Ninety minutes crosses the hour boundary, so no single cron expression covers it. Two lines stepping the hour field by 3 give an exact 16 run day.
Cron every 30 minutes: */30 * * * *
*/30 * * * * fires 48 times a day at minutes 0 and 30. The half hour is the busiest slot on most servers, and 15,45 costs nothing to move to.
Cron every 5 hours: 0 */5 * * * and the four hour gap
0 */5 * * * fires five times a day at 00:00, 05:00, 10:00, 15:00 and 20:00, then waits four hours instead of five. Here is why and what to do.
Cron step values: what */n really does
*/n walks a field from its minimum in increments of n. Because it starts at the field minimum, */2 gives even minutes and odd days of the month.
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