Every 2 Hours Cron Expression
Runs at midnight, 2 AM, 4 AM, 6 AM, … 12 times per day.
0 */2 * * * in POSIX cron
Expression
0 */2 * * *Try it in the tester →Field Breakdown
How It Works
Minute fixed at 0, hour uses `*/2` — fires on every even hour of the day.
Example Run Times
- 00:00:00
- 02:00:00
- 04:00:00
- 06:00:00
- 08:00:00
Frequently Asked Questions
Does this fire on odd hours?
No. `*/2` starts at 0 and steps by 2, so it lands on 0, 2, 4, …, 22 — all even hours.
0 */2 * * * in Quartz / Spring
The step moves up into the hour field here: 12 runs per day on the even hours — 00:00, 02:00, 04:00, and so on through 22:00. Seconds and minutes are both locked to zero.
Quartz / Spring expression
0 0 */2 * * ?Try it in the tester →At second 0, at minute 0, every 2 hours
Unix / POSIX equivalent: 0 */2 * * *
Field Breakdown
Using It with Quartz / Spring
Two-hourly suits medium-weight maintenance: re-indexing search shards, refreshing materialized views, or pulling delta feeds from a vendor SFTP drop that updates a few times a day. Register it in Quartz via newTrigger().withIdentity("feedPull").withSchedule(CronScheduleBuilder.cronSchedule("0 0 */2 * * ?")), or hand the string to Spring's @Scheduled. Because firings are two hours apart, set an explicit misfire instruction — withMisfireHandlingInstructionFireAndProceed() versus DoNothing() makes a real difference after a long deploy window.
Quartz-Specific Notes
- →*/2 anchors at hour 0, so this always means even hours; there is no way for the step form alone to produce 01:00, 03:00, etc.
- →For odd hours, write the range-with-step form 1-23/2 (or 1/2) in the hour field instead.
- →All twelve firings track the trigger's timezone — a JVM in Europe/Berlin and one in UTC running this same string fire an hour or two apart on the absolute timeline.
Frequently Asked Questions
How do I get every 2 hours starting at 09:00?
Use 0 0 9/2 * * ? — the slash after a literal start value steps from there, giving 09:00, 11:00, 13:00, …, 23:00, then resuming at 09:00 the next day.
Why did my run at 02:00 vanish one night in March?
Spring-forward DST. If your trigger timezone skips from 02:00 to 03:00, the 02:00 slot doesn't exist that day, so that single firing is lost — eleven runs instead of twelve.
0 */2 * * * in AWS EventBridge
With the minute fixed at 0 and an */2 step on the hour field, this rule fires on every even UTC hour — 12 runs per day at 00:00, 02:00, 04:00 and onward through 22:00. It suits batch work that is too heavy to run hourly but cannot wait for a nightly window.
AWS EventBridge expression
cron(0 */2 * * ? *)Try it in the tester →Every 2 hours on the hour UTC
Unix / POSIX equivalent: 0 */2 * * *
Field Breakdown
Using It with AWS EventBridge
Configure it as the ScheduleExpression of an EventBridge rule or Scheduler schedule and aim it at a Step Functions state machine or an ECS RunTask for the heavier lifting two-hourly jobs usually involve. Common uses are warehouse incremental loads, S3-to-Redshift COPY batches, and ML feature refreshes where a two-hour staleness budget was negotiated with the data consumers. The even-hour alignment means the schedule never drifts relative to other UTC-anchored systems.
AWS-Specific Notes
- →Because the step starts from hour 0, all twelve runs land on even hours; odd hours (01:00, 03:00...) never match.
- →To fire on odd hours instead, use the start/step form cron(0 1/2 * * ? *).
- →Classic rules ignore local time entirely — 00:00 UTC is 19:00 or 20:00 US Eastern depending on DST, so the even-hour pattern looks odd-houred to East Coast observers half the year.
Frequently Asked Questions
Why does my every-2-hours rule run at odd local hours after the DST change?
EventBridge rules evaluate in UTC, which has no DST. Your local clock shifted, the rule did not. Move to EventBridge Scheduler with ScheduleExpressionTimezone if local alignment matters.
Can a two-hourly run overlap the previous one if the job takes longer than two hours?
Yes — EventBridge fires regardless of whether the prior invocation finished. Guard with a Step Functions execution-already-running check, a DynamoDB lock, or Lambda reserved concurrency of 1.
0 */2 * * * in GitHub Actions
The */2 step in the hour field produces 12 runs per day at 00:00, 02:00, 04:00 and onward through 22:00 UTC — even hours only. Two-hourly is a common GitHub Actions cadence for heavier jobs that would be wasteful to run every hour but go stale overnight.
GitHub Actions expression
0 */2 * * *Try it in the tester →Every 2 hours on the hour UTC
Unix / POSIX equivalent: 0 */2 * * *
Field Breakdown
Using It with GitHub Actions
Written into workflow YAML as on: schedule: - cron: "0 */2 * * *", this drives jobs like rebuilding a documentation site from external sources, refreshing container base-image scans, or batching analytics events into a warehouse load. The matrix strategy pairs well with this cadence: one two-hourly trigger fanning out across OS or version matrices keeps total runner usage predictable. As with any minute-0 schedule, sliding to "42 */2 * * *" keeps the every-other-hour rhythm while skipping the congested slot.
GitHub-Specific Notes
- →Step values count from the field's minimum, so */2 in the hour field always means even UTC hours — there is no syntax to get odd hours except an explicit list like 1,3,5,7,9,11,13,15,17,19,21,23.
- →12 of this schedule's runs per day all start at minute :00, the platform's busiest slot, so each tick inherits top-of-hour delay.
- →Because evaluation is strictly UTC, the even-hour pattern lands on odd local hours in any UTC-offset-odd timezone — for example 01:00, 03:00 in CET winter.
Frequently Asked Questions
How do I run every 2 hours starting at 01:00 instead of 00:00?
Use the range-step form 0 1-23/2 * * * — it fires at the odd hours 01:00 through 23:00, twelve runs per day, shifted one hour from the */2 default.
Will the 02:00 run wait if the 00:00 run is still going?
Not by default — schedule ticks are independent and can overlap. Add a concurrency key to the workflow if two simultaneous instances would conflict.