Every 4 Hours Cron Expression
Runs six times per day: 00, 04, 08, 12, 16, 20.
0 */4 * * * in POSIX cron
Expression
0 */4 * * *Try it in the tester →Field Breakdown
How It Works
Step value `*/4` in the hour field — fires at hours 0, 4, 8, 12, 16, and 20 each day.
Example Run Times
- 00:00:00
- 04:00:00
- 08:00:00
- 12:00:00
- 16:00:00
Frequently Asked Questions
Does this divide the day evenly?
Yes — 24 / 4 = 6 fire points spaced exactly four hours apart.
0 */4 * * * in Quartz / Spring
Six executions per day, at 00:00, 04:00, 08:00, 12:00, 16:00, and 20:00 — the day sliced into four-hour blocks. The */4 step lives in the hour field, with seconds and minutes both locked at zero.
Quartz / Spring expression
0 0 */4 * * ?Try it in the tester →At second 0, at minute 0, every 4 hours
Unix / POSIX equivalent: 0 */4 * * *
Field Breakdown
Using It with Quartz / Spring
Four-hourly is a popular reconciliation rhythm: comparing an order ledger against a payment processor, syncing a CRM mirror, or recomputing recommendation candidates often enough to feel fresh without burning compute hourly. Annotate with @Scheduled(cron = "0 0 */4 * * ?") in Spring, or schedule a CronTrigger in Quartz. The 08:00, 12:00, and 16:00 firings conveniently bracket a standard business day, while 20:00, 00:00, and 04:00 keep overnight data from going stale before morning.
Quartz-Specific Notes
- →Field position is everything: the same */4 one slot to the left (0 */4 * * * ?) means every four minutes — 360 runs a day instead of 6. Misplacing a step across the seconds-first layout is the classic Quartz porting injury.
- →24 % 4 == 0, so the spacing is uniform around the clock, including from 20:00 across midnight to 00:00.
- →The explicit-list spelling 0 0 0,4,8,12,16,20 * * ? is interchangeable and self-documenting in a code review.
Frequently Asked Questions
I deployed this and got a run every four minutes — what went wrong?
The step landed in the minute field instead of the hour field. In Quartz's seconds-first layout the hour is the third token: 0 0 */4 * * ? is four-hourly, while 0 */4 * * * ? is four-minutely.
Can I skip the overnight firings and keep only daytime runs?
Yes — replace the step with a list of the hours you want: 0 0 8,12,16 * * ? fires at 08:00, 12:00, and 16:00 only, preserving four-hour spacing within the workday.
How do the six runs shift when daylight saving starts?
In zones that skip 02:00-03:00, none of this schedule's hours are inside the gap, so all six fire — but they're evaluated by local wall clock, so on the absolute timeline that day's runs sit one hour closer together than usual across the transition.
0 */4 * * * in AWS EventBridge
Six runs per day at 00:00, 04:00, 08:00, 12:00, 16:00, and 20:00 UTC — the hour step of 4 divides the day into six equal slices. This cadence covers a lot of operational housekeeping that hourly would overdo and daily would starve.
AWS EventBridge expression
cron(0 */4 * * ? *)Try it in the tester →Every 4 hours on the hour UTC
Unix / POSIX equivalent: 0 */4 * * *
Field Breakdown
Using It with AWS EventBridge
Four-hourly EventBridge rules commonly drive certificate and secret expiry sweeps, S3 lifecycle pre-checks, batch enrichment of newly ingested records, and pulling partner data feeds published a handful of times a day. Put the expression in the rule, choose targets — a Lambda plus an SNS topic for failures is a typical pair — and let the rule's event payload timestamp tell the function which slice it is processing. With six slices a day, a job that processes since-last-run deltas should persist its own watermark rather than assuming exactly four hours elapsed, since an occasional late or duplicate delivery can bend the interval slightly.
AWS-Specific Notes
- →The six UTC firing times map to 8 PM, midnight, 4 AM, 8 AM, noon, and 4 PM US Eastern during daylight saving — three of the six land in the US workday.
- →cron(0 0,4,8,12,16,20 * * ? *) is the same schedule written as a list; some teams prefer it because the firing hours are visible at a glance.
- →rate(4 hours) matches the frequency but unmoors the runs from these clock hours, anchoring to schedule creation instead.
Frequently Asked Questions
Can I shift this to 02:00, 06:00, 10:00 and so on?
Yes, with an explicit hour list: cron(0 2,6,10,14,18,22 * * ? *). The */4 shorthand always starts at hour 0, so any offset pattern has to be spelled out.
Will exactly four hours separate consecutive runs?
Nominally yes, but EventBridge may deliver up to a minute late under load and occasionally more than once, so the real gap wobbles around four hours. Compute deltas from a stored watermark, not from an assumed interval.
0 */4 * * * in GitHub Actions
Six touchpoints per day: the */4 hour step fires at 00:00, 04:00, 08:00, 12:00, 16:00, and 20:00 UTC, evenly spaced because 4 divides 24. It is the cadence of choice when hourly is overkill but a six-hour gap feels too exposed.
GitHub Actions expression
0 */4 * * *Try it in the tester →Every 4 hours on the hour UTC
Unix / POSIX equivalent: 0 */4 * * *
Field Breakdown
Using It with GitHub Actions
Set up as on: schedule: - cron: "0 */4 * * *" in workflow YAML on the default branch, four-hourly scheduling carries mid-weight recurring jobs: uploading database snapshots as workflow artifacts, sweeping container registries for newly published base-image patches, or running synthetic end-to-end checks against production. The four-hour gap caps how stale any monitored signal can get at a level most on-call rotations find acceptable.
GitHub-Specific Notes
- →Mapped to US Eastern under standard time, the six anchors land at 19:00, 23:00, 03:00, 07:00, 11:00, and 15:00 local — note that two of them fall on the previous calendar day.
- →The step counts from hour 0; for anchors at 02, 06, 10, 14, 18, and 22 UTC instead, write "0 2-23/4 * * *".
- →Worst-case data staleness is just under four hours plus whatever queue delay the tick incurs — budget freshness guarantees against that sum, not against the nominal interval.
Frequently Asked Questions
Exactly when does 0 */4 * * * run each day?
Six times: 00:00, 04:00, 08:00, 12:00, 16:00, and 20:00, all UTC. The pattern repeats identically every day of the year because schedules are UTC-only and 4 divides 24 without remainder.
Can I confine the four-hourly runs to a working-hours window?
Yes — bound the hour range: "0 8-20/4 * * *" fires at 08:00, 12:00, 16:00, and 20:00 UTC only. Convert your local working window to UTC hours first, since there is no timezone option.