Run a cron job every 4 hours

0 */4 * * * Check it below, then take the line for any of 17 schedulers.

Click to edit · paste a crontab line · hover a field for its values

At 00:00, 04:00, 08:00, 12:00, 16:00 and 20:00 every day.

 

Nothing to watch out for on Debian / Ubuntu cron.

crontab line
# crontab -e  (runs on the server's clock: UTC)
0 */4 * * *  /path/to/command
Debian / Ubuntu cron RunWisp Server was off Skipped. anacron only catches up cron.daily, weekly and monthly. Runs the most recent missed run at start-up (catch_up = 1) and sends a missed-run alert.A run fails Output is mailed if MAILTO and a mail server work. No output, no mail, whatever the exit code. Marked failed and sent to your alert channels. retry_attempts adds retries.

· sudo runwisp takeover runs your crontab as it is · How RunWisp compares

Details

Upcoming runs
Calendar Every day
Between two dates
Daylight saving

When things go wrong Server off: Skipped
Server was off
Skipped. anacron only catches up cron.daily, weekly and monthly.
Last run still going
Starts another copy on top.
A run fails
Output is mailed if MAILTO and a mail server work. No output, no mail, whatever the exit code.
Time zone
The server's zone. TZ= in a crontab only reaches the command.
Precision
1 minute.

Sources: manpages.debian.org,manpages.debian.org

Other schedulers As written in 10 of 16
  • ✓ cronie 0 */4 * * * vs RunWisp
  • ✓ BusyBox crond 0 */4 * * *
  • ↻ systemd timer *-*-* 00/4:00:00 UTC systemd timer uses OnCalendar=, not cron lines. vs RunWisp
  • ✓ RunWisp 0 */4 * * *
  • ✓ Kubernetes CronJob 0 */4 * * *
  • ≠ Ofelia 0 0 */4 * * * Ofelia puts seconds first, so it reads this as: every 4 minutes. vs RunWisp
  • ✓ Dagu 0 */4 * * * vs RunWisp
  • ✓ PM2 cron_restart 0 */4 * * * vs RunWisp
  • ≠ Jobber 0 0 */4 * * * Jobber puts seconds first, so it reads this as: every 4 minutes. vs RunWisp
  • ✓ GitHub Actions 0 */4 * * *
  • ✓ GitLab CI schedule 0 */4 * * *
  • ↻ AWS EventBridge Scheduler cron(0 */4 * * ? *) AWS EventBridge Scheduler takes cron() with 6 fields, a year last, and ? in one day field.
  • ✓ Google Cloud Scheduler 0 */4 * * *
  • ✓ Jenkins 0 */4 * * *
  • ↻ Quartz 0 0 */4 * * ? Quartz takes 6 or 7 fields, seconds first, with ? in one day field.
  • ↻ Spring @Scheduled 0 0 */4 * * * Spring @Scheduled takes exactly 6 fields, seconds first.

✓ works as written · ↻ different syntax · ≠ runs at other times · ? not documented · ✗ can't

Schedulers

Every 4 hours, in every scheduler

Works as written in 11 of 17. Times are UTC; the checker above takes any zone.

Runs in 2027
2,190
Days with a run
365
Longest gap
4 h
SchedulerLineNotes
Debian / Ubuntu cron ✓ 0 */4 * * * Works as written.
cronie ✓ 0 */4 * * * Works as written.
BusyBox crond ✓ 0 */4 * * * Works as written.
systemd timer ↻ OnCalendar=*-*-* 00/4:00:00 UTC systemd timer uses OnCalendar=, not cron lines.
RunWisp ✓ 0 */4 * * * Works as written.
Kubernetes CronJob ✓ 0 */4 * * * Works as written.
Ofelia ≠ 0 0 */4 * * * Ofelia puts seconds first, so it reads this as: every 4 minutes.
Dagu ✓ 0 */4 * * * Works as written.
PM2 cron_restart ✓ 0 */4 * * * Works as written.
Jobber ≠ 0 0 */4 * * * Jobber puts seconds first, so it reads this as: every 4 minutes.
GitHub Actions ✓ 0 */4 * * * Works as written.
GitLab CI schedule ✓ 0 */4 * * * Works as written.
AWS EventBridge Scheduler ↻ cron(0 */4 * * ? *) AWS EventBridge Scheduler takes cron() with 6 fields, a year last, and ? in one day field.
Google Cloud Scheduler ✓ 0 */4 * * * Works as written.
Jenkins ✓ 0 */4 * * * Works as written.
Quartz ↻ 0 0 */4 * * ? Quartz takes 6 or 7 fields, seconds first, with ? in one day field.
Spring @Scheduled ↻ 0 0 */4 * * * Spring @Scheduled takes exactly 6 fields, seconds first.

✓ works as written · ↻ different syntax · ≠ runs at other times · ? not documented · ✗ can't

RunWisp

Cron runs the line. Nobody tells you how it went.

RunWisp is an open-source cron replacement that ships as a single binary. It reads the same cron line and keeps a record of every run: output, exit code, duration.

crontab
# crontab -e  (runs on the server's clock: UTC)
0 */4 * * *  /usr/local/bin/job.sh
runwisp.toml
[tasks.job]
cron     = "0 */4 * * *"
timezone = "UTC"
run      = '/usr/local/bin/job.sh'
cronRunWisp
The server was off at run time Skipped. anacron only catches up cron.daily, weekly and monthly. Runs the most recent missed run at start-up (catch_up = 1) and sends a missed-run alert.
The last run is still going Starts another copy on top. Queues it. on_overlap = "queue" is the default.
A run fails Output is mailed if MAILTO and a mail server work. No output, no mail, whatever the exit code. Marked failed and sent to your alert channels. retry_attempts adds retries.

Keep your crontab. sudo runwisp takeover runs it where it is and retires cron, crontab -e keeps working, and runwisp service uninstall puts cron back. It needs Linux with systemd; elsewhere, runwisp import cron converts the file. RunWisp doesn't do L, W or #, and it runs on one machine, not a cluster. Moving from cron →

FAQ

Questions

What does 0 */4 * * * mean?
At 00:00, 04:00, 08:00, 12:00, 16:00 and 20:00 every day. In 2027 that's 2,190 runs on 365 days. Times are in the scheduler's time zone, usually the server's.
How do I run a job every 4 hours with a systemd timer?
OnCalendar=*-*-* 00/4:00:00 UTC. systemd timer uses OnCalendar=, not cron lines.
How do I run a job every 4 hours in a Kubernetes CronJob?
0 */4 * * * works as written.
How do I run a job every 4 hours in GitHub Actions?
0 */4 * * * works as written.
How do I run a job every 4 hours on AWS EventBridge?
cron(0 */4 * * ? *). AWS EventBridge Scheduler takes cron() with 6 fields, a year last, and ? in one day field.
More
Get started
GPL 3.0 · no accounts · free to self-host

Start in 30 seconds. Ship on your terms.

A single Go binary. If it doesn't earn the disk space, rm it. No account, no signup, no catch.

Install in 30 seconds
curl -fsSL https://get.runwisp.com | sh