0 */4 * * * — What does this cron expression mean?
0 */4 * * * gives you six evenly spaced runs a day, which works well for jobs that need to happen during working hours on more than one continent. Like every hour step, it counts wall-clock hours from midnight. On the two days a year when clocks change, one of the gaps is 3 or 5 real hours, not 4.
0 */4 * * *
Run the job every 4 hours, on the hour: at 00:00, 04:00, 08:00, 12:00, 16:00 and 20:00.
Frequency: 6 runs per day. cronstrue reads it as “On the hour, every 4 hours”.
Open 0 */4 * * * in the Cron BuilderField-by-field breakdown
0
Minute
0–59
*/4
Hour
0–23
*
Day of month
1–31
*
Month
1–12
*
Day of week
0–6
- Minute0 — only at minute 0.
- Hour*/4 — every 4th hour starting at 0: 0, 4, 8, 12, 16, 20.
- Day of month* — every day of the month.
- Month* — every month.
- Day of week* — every day of the week.
Next run times
Example: if it is Monday, 5 Jan 2026, 09:07 UTC, the next runs of 0 */4 * * * (UTC) are:
- #1Mon, 5 Jan 2026, 12:00 UTC
- #2Mon, 5 Jan 2026, 16:00 UTC
- #3Mon, 5 Jan 2026, 20:00 UTC
- #4Tue, 6 Jan 2026, 00:00 UTC
- #5Tue, 6 Jan 2026, 04:00 UTC
Live times from your current clock replace this example once the page loads. Cron uses the scheduler's timezone; most cloud servers, GitHub Actions and AWS EventBridge rules use UTC.
0 */4 * * * in Quartz, AWS, GitHub Actions, Kubernetes and systemd
Crontab (Linux / macOS)
0 */4 * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1Standard 5-field syntax used by Vixie cron, cronie, busybox crond and most libraries (node-cron, APScheduler, robfig/cron).
Quartz (6 and 7 fields)
0 0 0/4 * * ?
0 0 0/4 * * ? *
# Spring @Scheduled
@Scheduled(cron = "0 0 */4 * * *")Quartz also supports ranges with steps, such as 0 0 8-20/4 * * ? for 08:00, 12:00, 16:00 and 20:00 only.
AWS EventBridge
cron(0 0/4 * * ? *)
# interval alternative
rate(4 hours)Runs at 00, 04, 08, 12, 16 and 20 UTC. Since EventBridge rules are UTC-only, there is no DST effect, which is one reason to keep interval jobs in UTC.
GitHub Actions
on:
schedule:
# Every 4 hours, evaluated in UTC
- cron: '0 */4 * * *'Runs at the same six UTC times every day. For a release or dependency-check workflow, offsetting the minute (for example 23 */4 * * *) reduces queueing delays.
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: every-4-hours
spec:
schedule: "0 */4 * * *"
timeZone: "Etc/UTC"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1200
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: job
image: alpine:3.20
command: ["/bin/sh", "-c", "echo running"]A 20-minute deadline gives the Job time to start after a brief controller outage without risking overlap with the next run.
systemd timer
# /etc/systemd/system/myjob.timer
[Unit]
Description=Every 4 hours
[Timer]
OnCalendar=*-*-* 00/4:00:00
Persistent=true
[Install]
WantedBy=timers.targetExplicit equivalent: *-*-* 00,04,08,12,16,20:00:00.
When to use every 4 hours
- Syncing CRM or ERP data into a warehouse a few times per business day.
- Checking for upstream dependency or container image updates.
- Sending shift-change reports for teams working in 8-hour shifts (every other run).
- Rotating logs on busy hosts where daily rotation produces files that are too large.
Common pitfalls with 0 */4 * * *
DST makes one interval 3 or 5 hours long
If the scheduler runs in a local timezone with daylight saving, the hour field means wall-clock hours. In the US, on the spring-forward night the 00:00 and 04:00 runs are only 3 real hours apart, because 02:00 to 03:00 doesn't exist. In autumn that gap is 5 hours. If you need strict 4-hour spacing, run the scheduler in UTC.
Don't forget the minute
* */4 * * * runs every minute during hours 0, 4, 8, 12, 16 and 20, which is 360 runs a day. The leading 0 is what makes it once per block.
# WRONG: 360 runs/day
* */4 * * *
# RIGHT: 6 runs/day
0 */4 * * *Business hours only
If the job is only useful during the working day, restrict it with a range-step instead of running at midnight and 04:00 for nothing.
# 08:00, 12:00, 16:00, 20:00, Monday to Friday
0 8-20/4 * * 1-5Related cron expressions
Need a different schedule? Paste 0 */4 * * * into the Cron Builder and edit it, browse all cron expressions, read the cron syntax guide or copy from the cron examples list.
Frequently Asked Questions
What does 0 */4 * * * mean in cron?▾
Every 4 hours on the hour. It runs at 00:00, 04:00, 08:00, 12:00, 16:00 and 20:00 every day in the scheduler's timezone, six times in total.
What is the difference between 0 */4 * * * and 0 0/4 * * *?▾
In Quartz and AWS they mean the same: every 4th hour starting at 0. In a crontab, use */4 (or 0-23/4); a step after a single number such as 0/4 is not portable across cron daemons, and some reject it.
How do I run every 4 hours but only on weekdays?▾
0 */4 * * 1-5 runs at the six 4-hour marks Monday to Friday. 0 8-20/4 * * 1-5 limits it to 08:00, 12:00, 16:00 and 20:00.