0 */12 * * * runs a job twice a day, at midnight and noon. The 0 pins the minute, and */12 in the hour field picks hours 0 and 12, so 0 0,12 * * * is the same schedule.
When it fires
Checked at 09:58 UTC on October 14, the next five runs are:
Oct 14 12:00 Oct 15 00:00 Oct 15 12:00 Oct 16 00:00 Oct 16 12:00
The runs follow the clock, not the moment you install the job, so the first can come anywhere up to twelve hours later. For another pair of hours twelve apart, list them: 0 6,18 * * * runs at 06:00 and 18:00.
Put the step in the hour field
*/12 * * * * looks close but steps the minute field: it runs every 12 minutes, at 10:00, 10:12, 10:24, 10:36 and 10:48, 120 times a day. The hour is the second field, and the minute before it needs a number, or * */12 * * * runs every minute of hours 0 and 12.
Twelve hours, or two clock times?
Cron matches clock times in its timezone. In a zone with daylight saving time, midnight and noon are 11 hours apart on the day clocks spring forward and 13 on the day they fall back. Run with America/New_York, where clocks fall back on November 1, 2026, the schedule fires at:
Oct 31 12:00 EDT Nov 1 00:00 EDT Nov 1 12:00 EST Nov 2 00:00 EST
Midnight to noon on November 1 is 13 hours. When the interval matters more than the clock, schedule in UTC, or use a timer that counts time: EventBridge’s rate(12 hours), or a systemd timer’s OnUnitActiveSec=12h.
The same schedule elsewhere
- crontab:
0 */12 * * * /usr/local/bin/backup.sh, or0 0,12 * * *. - GitHub Actions:
cron: '0 */12 * * *', in UTC, so daylight saving time doesn’t move it. - Kubernetes CronJob:
schedule: "0 */12 * * *", withspec.timeZonefor a local midnight and noon. - AWS EventBridge:
cron(0 0/12 * * ? *). - systemd timer:
OnCalendar=0/12:00, whichsystemd-analyze calendarnormalizes to*-*-* 00/12:00:00. - Spring
@Scheduled:0 0 */12 * * *.