Every hour cron: what 0 * * * * means and why the top of the hour is crowded
Runs in your browser — nothing you paste leaves this page. How we prove that
Cron Expression Tester playground
Five fields — minute, hour, day of month, month, day of week. Macros like @daily are supported too.
Results update as you type — press Enter to run now.
Every hour at :00.
- Computed in your browser, in your timezone.
`0 * * * *` fires once an hour, at minute zero. The engine reads it as: Every hour at :00.
Reading 0 * * * *
The minute field is a literal 0 and every other field is a wildcard, so the job runs at minute 0 of every hour: 24 times a day. The macro @hourly means the same thing in Vixie cron, cronie and Kubernetes.
The parser on this page reads it as: Every hour at :00. The next run times in the panel above are computed in your browser, in your own timezone, so they are not printed in this text.
The classic mistake is * */1 * * *. That puts the wildcard in the minute field, so it matches every minute of every hour, sixty runs an hour instead of one. The hour step is redundant; the minute field is the one that has to be pinned.
A crontab line
0 * * * * /usr/bin/logrotate /etc/logrotate.d/app-hourly is a typical hourly job. If the work can take longer than an hour, guard it with flock -n /run/lock/app-hourly.lock in front of the command so the next run exits instead of overlapping.
The top of the hour is crowded
Minute 0 is the most popular minute in every crontab. Backups, report jobs, certificate checks and cache refreshes all land there, and on shared infrastructure that turns into a load spike every hour. GitHub explicitly warns that scheduled workflows are most likely to be delayed or dropped at the start of an hour. Picking an odd minute, such as 17 * * * *, keeps the hourly cadence and dodges the queue.
Daylight saving affects hourly jobs mildly: the skipped hour loses one run and the repeated hour may run twice, depending on the cron implementation. If each run processes the previous hour of data, compute the window from UTC timestamps rather than from the local clock.
systemd, Kubernetes and GitHub Actions
The systemd timer is OnCalendar=hourly, the same as *-*-* *:00:00; add Persistent=true if a run missed while the machine was off should happen at the next boot. Kubernetes accepts both 0 * * * * and @hourly. GitHub Actions accepts 0 * * * * in UTC but does not support the @hourly macro. Neighbouring schedules: every 30 minutes doubles the runs, every day at midnight reduces them to one.
FAQ
Questions, answered.
Tap a question to expand the answer.
What is the difference between 0 * * * * and @hourly?
None in cron implementations that support macros: @hourly is defined as 0 * * * *. GitHub Actions does not accept the macro, so use the five-field form there.
How do I run every 2 hours?
Pin the minute and step the hour: 0 */2 * * * runs at 00:00, 02:00, 04:00 and so on.
More free, private DevOps tools.
The Cron Expression Tester is one tool in OpsCanopy — a growing canopy of browser-based validators, converters and testers that never touch a server.
More in Scheduling
Read more about this
- GitHub Actions cron runs in UTC: convert your schedule and check the real next run time GitHub Actions cron timezone UTC explained: why schedule: cron: always fires on UTC, how DST shifts the wall-clock time, and how to check the real next run.
- Reading cron expressions: a field-by-field guide A field-by-field guide to reading cron expressions — the five time fields, ranges, steps, lists and @macros — plus the gotchas that misfire schedules.
New to Linux? Read the Linux guide →
42 free tools, every one offline-capable — opscanopy.com works with no signup and nothing uploaded.
Scheduling on Linux? Pair this with the Cron to systemd Converter, or browse the full tools directory.
Not affiliated with or endorsed by any cron implementation. Format names are used only to describe what this tool reads. OpsCanopy is free and open.