Cron expression for every 2 hours
The cron expression 0 */2 * * * runs a job every 2 hours on the hour — at 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 (12 firings per day). The */2 is step syntax: “every 2 units starting from 0”. The step works in any cron field; */2 in the day-of-month field would mean “every other day”, */2 in the minute field means “every other minute”.
Quick reference
| Platform | Expression |
|---|---|
| Unix / Linux crontab | 0 */2 * * * |
| Kubernetes CronJob | 0 */2 * * * |
| GitHub Actions | 0 */2 * * * |
| AWS EventBridge | cron(0 0/2 * * ? *) |
| Quartz (Java) | 0 0 0/2 ? * * |
How does step syntax (*/N) work?
*/N reads as “every N units starting from the lowest legal value of this field”. In the minute field (range 0–59), */15 hits 0, 15, 30, 45. In the hour field (range 0–23), */2 hits 0, 2, 4, …, 22. In the day-of-month field (range 1–31), */5 hits 1, 6, 11, 16, 21, 26, 31.
The “starting from 0” matters when N is not a divisor of the field’s range. For divisors of 24 — */2, */3, */4, */6, */8, */12 — the firings are evenly spaced across the day. For non-divisors — */5, */7, */9, */11 — there’s a gap at the day boundary because the count restarts at hour 0.
For example, */5 * * * in the hour field fires at 0, 5, 10, 15, 20. Then the day rolls over and the next firing is at hour 0 of the next day — a 4-hour gap, not 5.
If you want truly evenly-spaced “every N hours” and N is not a divisor of 24, you can’t get it with cron alone. Use a long-running scheduler that tracks elapsed time, or accept the day-boundary gap.
Variations
| Schedule | Expression |
|---|---|
| Every 2 hours on the hour | 0 */2 * * * |
| Every 2 hours starting at 1 AM (1, 3, 5, 7, …) | 0 1-23/2 * * * |
| Every 2 hours during business hours (9 AM – 5 PM) | 0 9-17/2 * * * |
| Every 3 hours | 0 */3 * * * |
| Every 4 hours | 0 */4 * * * |
| Every 6 hours | 0 */6 * * * |
| Every 12 hours (twice daily) | 0 */12 * * * (= 0 0,12 * * *) |
| Every 2 hours in AWS | cron(0 0/2 * * ? *) |
How do I use it on each platform?
Linux crontab:
0 */2 * * * /usr/local/bin/health-check
Kubernetes CronJob:
apiVersion: batch/v1
kind: CronJob
metadata:
name: health-check
spec:
schedule: "0 */2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: check
image: my-org/health-check:1.0
restartPolicy: OnFailure
AWS EventBridge:
aws events put-rule \
--name health-check \
--schedule-expression "cron(0 0/2 * * ? *)"
EventBridge’s rate(2 hours) is an alternative that fires every 2 hours from rule-creation time — no clock alignment. Use cron() for clock-aligned 00:00, 02:00, 04:00; use rate() if you don’t care about the wall-clock minute.
GitHub Actions:
on:
schedule:
- cron: '0 */2 * * *'
Common mistakes
Expecting */5 in the hour field to be evenly spaced across the day boundary. It hits 0, 5, 10, 15, 20 — then resets to 0 the next day, leaving a 4-hour gap. If you need “every 5 hours from when the job was created”, use a rate() expression or a long-running scheduler.
Putting the step in the wrong field. */2 * * * * (step in MINUTE field) means every 2 minutes — 720 runs per day. 0 */2 * * * is what you want for every 2 hours. Easy mis-paste.
Using 0 */2 * * ? * in AWS without 0/2. Both work in modern AWS, but the older docs say only 0/2 is valid. For maximum compatibility with old IaC validators and copy-paste guides, prefer 0/2. The AWS EventBridge cron generator emits 0/N step syntax by default and includes ready-to-paste CloudFormation, Terraform and CLI snippets. For the Kubernetes side — full CronJob YAML with concurrencyPolicy and timeZone — use the Kubernetes CronJob schedule generator.
For other schedules see common cron schedules, or build a custom expression with the Cron Expression Builder.
Frequently asked questions
- How does the step syntax
*/2work? */Nmeans "every N units, starting from the lowest legal value". In the hour field,*/2fires at 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22 — every other hour. In the minute field*/15fires at 0, 15, 30, 45. The step starts from the field minimum, not from when cron started.- Why doesn''t
0 */5 * * *run "every 5 hours"? - It does run every 5 hours in a sense, but the result might surprise you.
*/5in the hour field hits 0, 5, 10, 15, 20 — five firings per day, with a 4-hour gap between hour 20 and hour 0 of the next day (because the day rolls over and the step resets). For divisors of 24 (*/2,*/3,*/4,*/6,*/8,*/12), the gap is uniform. For non-divisors (*/5,*/7,*/9,*/11), the schedule is uneven across the day boundary. - What''s the difference between
*/2and0/2in the hour field? */2and0/2are equivalent in standard Unix cron — both mean "every 2 starting from 0". AWS EventBridge prefers0/2syntactically; older AWS docs claim*/2is invalid (it isn't — it works), but0/2is the safer form for AWS-targeted IaC. To start at a different value, use the explicit form:5/2means 5, 7, 9, 11, 13, 15, 17, 19, 21, 23.
Need a different schedule?
Build cron expressions for Unix, Kubernetes, AWS EventBridge and Quartz — with a human-readable description and the next 5 run times.
Open the Cron Expression Builder →Related
Cron expression for every 3 hours
The cron expression 0 */3 * * * runs every 3 hours on the hour — 8 firings per day with no day-boundary gap. Linux/Kubernetes/GitHub Actions; cron(0 */3 * * ? *) in AWS.
Cron expression for every 30 minutes
The cron expression */30 * * * * runs every 30 minutes — at :00 and :30 of every hour. Same in Linux, Kubernetes and GitHub Actions; cron(*/30 * * * ? *) in AWS.
Cron expression for every 30 seconds
Cron cannot run every 30 seconds — it has no seconds field, only minutes. Use setInterval, KEDA cron-trigger or a long-running scheduler instead.
Cron expression for every 4 hours
The cron expression 0 */4 * * * runs every 4 hours on the hour — at 00:00, 04:00, 08:00, 12:00, 16:00 and 20:00. Six runs per day across Linux, Kubernetes and GitHub Actions; cron(0 */4 * * ? *) in AWS.
Cron expression for every 5 minutes
The cron expression */5 * * * * runs every 5 minutes in Linux crontab, Kubernetes, GitHub Actions; cron(*/5 * * * ? *) in AWS EventBridge.
Cron expression for every hour
The cron expression 0 * * * * runs once per hour on the hour. Same syntax in Linux, Kubernetes and GitHub Actions; cron(0 * * * ? *) in AWS EventBridge.