Every 3 Hours Cron Expression
Runs eight times per day at 00:00, 03:00, 06:00, …
0 */3 * * * in POSIX cron
Expression
0 */3 * * *Try it in the tester →Field Breakdown
How It Works
Minute pinned to 0, hour uses `*/3` — fires at 0, 3, 6, 9, 12, 15, 18, 21 hours of every day.
Example Run Times
- 00:00:00
- 03:00:00
- 06:00:00
- 09:00:00
- 12:00:00
Frequently Asked Questions
Is `0 0,3,6,9,12,15,18,21 * * *` equivalent?
Yes — same eight fire points, written explicitly.
0 */3 * * * in Quartz / Spring
Eight firings a day at 00:00, 03:00, 06:00, 09:00, 12:00, 15:00, 18:00, and 21:00. The step sits in the hour field this time, and since 24 divides evenly by 3, the 21:00-to-midnight wrap is the same three-hour gap as the rest.
Quartz / Spring expression
0 0 */3 * * ?Try it in the tester →At second 0, at minute 0, every 3 hours
Unix / POSIX equivalent: 0 */3 * * *
Field Breakdown
Using It with Quartz / Spring
Three-hourly fits refresh work whose source changes several times a day but tolerates staleness measured in hours: rotating service credentials whose TTL comfortably exceeds three hours, pulling delta exports from a partner system, or compacting an event queue before it grows unwieldy. Spring binds it with @Scheduled(cron = "0 0 */3 * * ?"); Quartz proper with a CronTrigger. Eight runs spaced this widely also make a pleasant rhythm for progressive batch jobs that process "everything since the last run" — each window is bounded and predictable.
Quartz-Specific Notes
- →Seconds and minutes are both pinned to 0, so every execution starts at hh:00:00 exactly — the same instant top-of-hour jobs fire, eight times a day.
- →Shifting the minute decouples it from that crowd: 0 30 */3 * * ? keeps the eight-run cadence but lands at 00:30, 03:30, 06:30, and so on.
- →In US zones, the spring-forward jump from 02:00 straight to 03:00 leaves this schedule intact — none of its fire times fall inside the skipped 02:00 hour, and 03:00 itself still occurs at the transition instant.
Frequently Asked Questions
Is this identical to listing the hours explicitly?
Yes — 0 0 0,3,6,9,12,15,18,21 * * ? produces the same eight fire times. The step form is terser; the list makes the actual hours visible to reviewers at a glance.
Can I keep eight runs a day but avoid the exact top of the hour?
Move the minute field: 0 30 */3 * * ? fires at half past (00:30, 03:30, ...), or even pick an odd second like 30 0 */3 * * ? to stay one half-minute clear of hh:00:00 — a knob unique to seconds-aware cron.
0 */3 * * * in AWS EventBridge
Minute 0 combined with an hour step of 3 yields eight firings a day at 00:00, 03:00, 06:00, 09:00, 12:00, 15:00, 18:00, and 21:00 UTC. Because 24 divides cleanly by 3, the pattern repeats identically every day with no seam at midnight.
AWS EventBridge expression
cron(0 */3 * * ? *)Try it in the tester →Every 3 hours on the hour UTC
Unix / POSIX equivalent: 0 */3 * * *
Field Breakdown
Using It with AWS EventBridge
Eight evenly spaced daily runs suit medium-freshness pipelines: compacting and shipping log batches, refreshing materialized views that back internal dashboards, pulling marketplace pricing data, or re-scoring a recommendation cache. Set the expression on a rule and target Lambda for quick jobs or a Step Functions workflow for anything multi-stage; one rule's five-target allowance often covers the whole pipeline plus its notifier. When sizing the downstream system, remember every consumer of this rule receives the same eight-per-day pulse — staggering separate rules across offset hours spreads the load.
AWS-Specific Notes
- →The hour step starts from 0, so the run set always includes midnight UTC; in US Eastern the eight local firing times shift by an hour when DST changes, since the rule itself never moves off UTC.
- →An offset version needs an explicit list — cron(0 1,4,7,10,13,16,19,22 * * ? *) keeps three-hour spacing but skips the crowded top-of-day hours.
- →Eight runs daily is 2,920 per year per target, a useful figure when estimating Lambda or Step Functions cost for the pipeline.
Frequently Asked Questions
Which hours exactly does cron(0 */3 * * ? *) hit?
Hours 0, 3, 6, 9, 12, 15, 18, and 21 UTC, always at minute zero. It is exactly equivalent to listing those eight hours explicitly with commas.
Does the three-hour rhythm survive daylight saving time?
The UTC rhythm is untouched — classic rules do not observe DST at all. What changes is the local-time appearance: a run that lands at 07:00 in New York during winter lands at 08:00 after the spring switch. EventBridge Scheduler with a timezone keeps local times stable instead.
0 */3 * * * in GitHub Actions
Minute zero, hours stepped by three: eight runs a day at 00:00, 03:00, 06:00, 09:00, 12:00, 15:00, 18:00, and 21:00 UTC. Because 3 divides 24 evenly, the gaps are uniform and the same eight times recur every single day.
GitHub Actions expression
0 */3 * * *Try it in the tester →Every 3 hours on the hour UTC
Unix / POSIX equivalent: 0 */3 * * *
Field Breakdown
Using It with GitHub Actions
Configured as on: schedule: - cron: "0 */3 * * *" on the default branch, the three-hour beat suits freshness-sensitive but not urgent work: incremental ETL pulls from an upstream API, certificate and uptime probes that should catch problems within a workday fraction, or keeping a fork synchronized with a fast-moving upstream. Eight touchpoints a day keeps worst-case staleness under three hours while costing a fraction of an hourly schedule's runner time.
GitHub-Specific Notes
- →Hour steps count from 0, so the anchors are fixed at the multiples of three — the schedule phase-locks to the same UTC times daily and never drifts.
- →To shift the phase, use a range with the step: "0 1-22/3 * * *" fires at 01, 04, 07, 10, 13, 16, 19, and 22 UTC — still eight evenly spaced runs, one hour offset.
- →In zones with fractional offsets the anchors land off the hour locally: India at UTC+5:30 sees the runs at 05:30, 08:30, and so on — fixed year-round since IST has no daylight saving.
Frequently Asked Questions
Does */3 in the hour field mean three hours after the previous run?
No — it matches clock hours divisible by 3, evaluated against UTC. The schedule is anchored to fixed times of day, so a delayed 09:00 run does not push the 12:00 run later.
Can I keep the 3-hour spacing but skip the overnight UTC runs?
Constrain the hour range: "0 6-21/3 * * *" fires at 06, 09, 12, 15, 18, and 21 UTC — six daytime runs, dropping the 00:00 and 03:00 ticks.