Cron expression for every 2 hours

Free

0 */2 * * * - Every 2 hours, on the hour.

Field by field

0 */2 * * * reads: Every 2 hours, on the hour. That is 12 runs a day.

What each field of 0 */2 * * * selects
FieldValueSelects
Minute00
Hour*/2every 2 hours: 00:00, 02:00, 04:00, 06:00, 08:00, 10:00, 12:00, 14:00, 16:00, 18:00, 20:00 and 22:00
Day of month*any day of the month
Month*every month
Day of week*any day of the week

Worth knowing

  • 12 runs a day: 00:00, 02:00, 04:00 and on to 22:00.
  • */2 * * * * is every 2 minutes - the step belongs in the second field, and the minute must be fixed.
  • For the odd hours use 0 1-23/2 * * *.

Variations

  • 0 1-23/2 * * *Every 2 hours on the odd hoursExplain it
  • 30 */2 * * *Every 2 hours, at half pastExplain it

The same schedule elsewhere

crontab

0 */2 * * * /path/to/job.sh

Runs in the machine's local timezone. crontab -e to edit.

GitHub Actions

on:
  schedule:
    - cron: "0 */2 * * *"

Always UTC. Nothing more often than every 5 minutes, and runs can start late when GitHub is busy.

Kubernetes CronJob

spec:
  schedule: "0 */2 * * *"
  timeZone: "Asia/Kolkata"

timeZone needs Kubernetes 1.27 or later; without it the controller's zone applies, usually UTC.

Spring @Scheduled

@Scheduled(cron = "0 0 */2 * * *")

Six fields: seconds come first. Days are written as names, which Spring and cron read alike.

Quartz

0 0 0/2 * * ?

One of day-of-month and day-of-week must be ?. Quartz counts days 1-7 from Sunday, so names are safer than numbers.

AWS EventBridge

cron(0 0/2 * * ? *)

Six fields, the last one the year. UTC unless the schedule sets a timezone. Days count from Sunday, as in Quartz.

systemd timer

[Timer]
OnCalendar=*-*-* 00/2:00:00
Persistent=true

Persistent=true runs a job that was missed while the machine was off, once it is back.