Cron every day at 2 AM: 0 2 * * * and daylight saving
0 2 * * * runs once a day at 02:00 local time. It is the classic maintenance window and also the hour most affected by daylight saving transitions.
At a glance
- Expression
- 0 2 * * *
- Fires
- Once a day, 365 times in a non leap year, with two exceptions a year in zones that observe daylight saving.
- Restricted fields
- Minute pinned to 0, hour pinned to 2. Date fields open.
- Equivalent macro
- None. No macro can express a specific hour other than midnight.
- Local hour
- 02:00, in whatever timezone the cron daemon is running.
- Daylight saving risk
- In many zones the 02:00 hour is the one that is skipped in spring or repeated in autumn.
In detail
Two in the morning became the default maintenance window because it is after the evening peak and before the morning one in most consumer facing systems. The expression itself is unremarkable: one minute value, one hour value, and no date restriction, so it runs every night of the year.
The problem is that a lot of timezones make their daylight saving transition in or around this hour. Where the clock jumps forward, the 02:00 wall clock time simply does not exist on that date. Where it falls back, an hour of wall clock time is lived through twice. A schedule pinned to a wall clock hour has to be resolved somehow, and different cron implementations resolve it differently.
Some implementations run a job whose time was skipped once, immediately after the jump. Some skip it. On the repeat, some run once and some run twice. Because you cannot rely on which behaviour you have, the safe designs are to make the job idempotent, to record what it did rather than assuming it ran, or to run the daemon in UTC where no transition exists at all.
If the job must run in local time because it produces a report for humans, move it out of the transition window. 0 4 * * * is just as quiet and is not touched by any common transition rule, which removes the question without any change to what the job does.
Examples
0 2 * * *0 4 * * * /opt/app/bin/backup.sh >> /var/log/backup.log 2>&104:00 avoids the hour most zones move.
CRON_TZ=UTC
0 2 * * * /opt/app/bin/backup.shCRON_TZ is supported by several cron daemons but not all. Check yours before relying on it.
Things that catch people out
- A nightly backup that silently does not run once a year is very hard to notice, because the failure leaves no log line at all.
- Running twice is worse than not running for anything that appends. Make the job idempotent, or key its output by date so a second run overwrites rather than duplicates.
- Changing the server timezone changes when every wall clock job runs, including this one. That is a scheduling change, not a display setting.
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 day at midnight: 0 0 * * *
0 0 * * * runs once a day at 00:00 and is what both @daily and @midnight expand to. The midnight pile up, and why 0 24 * * * is invalid.
Cron every day at 9 AM: 0 9 * * *
0 9 * * * runs once a day at 09:00 in the server timezone, which on most containers is UTC. How to find out and how to fix it.
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 day at noon: 0 12 * * *
0 12 * * * runs once a day at midday. Cron has no AM or PM, so noon is hour 12 and midnight is hour 0, which is the pair people mix up.
Cron twice a day: 0 9,17 * * * at times you choose
0 9,17 * * * runs at 09:00 and 17:00 every day. A comma list handles times a step cannot, because the two gaps are eight and sixteen hours.
Cron during business hours: 0 9-17 * * 1-5
0 9-17 * * 1-5 runs hourly from 09:00 to 17:00 on weekdays, nine times a day and 45 times a week. The 17:00 run is included, not excluded.
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