To run a cron job every hour, on the hour, use:
0 * * * *
It fires at minute 0 of every hour: 00:00, 01:00, 02:00 and so on, 24 times a day. Most cron implementations also accept the shortcut @hourly. In a crontab:
0 * * * * /usr/local/bin/sync.sh >> /var/log/sync.log 2>&1
What each field means
| Field | Value | Meaning |
|---|---|---|
| Minute | 0 | at minute 0 |
| Hour | * | every hour |
| Day of month | * | every day |
| Month | * | every month |
| Day of week | * | every day of the week |
Variants
| Schedule | Expression |
|---|---|
| Every hour at :30 | 30 * * * * |
| Every hour from 9:00 to 17:00 | 0 9-17 * * * |
| Every hour on weekdays, 9:00 to 18:00 | 0 9-18 * * 1-5 |
| Every hour, weekends only | 0 * * * 0,6 |
| Every 2 hours | 0 */2 * * * (see every 2 hours) |
| Quartz (seconds first) | 0 0 * * * ? |
Spring @Scheduled | 0 0 * * * * or @hourly |
| AWS EventBridge | rate(1 hour) or cron(0 * * * ? *) |
Platform notes
- Linux crontab:
0 * * * *and@hourlyare equivalent. Hours follow the server's local time zone; on cronie (Fedora, RHEL) you can setCRON_TZat the top of the crontab to schedule in another zone. - GitHub Actions:
@hourlyisn't supported; write0 * * * *or, better, an odd minute, because the top of the hour is the busiest time and runs there are most likely to be delayed. See GitHub Actions cron. - Kubernetes CronJob:
@hourlyworks. Without.spec.timeZone, the hour is the kube-controller-manager's local time. - Cloudflare Cron Triggers: UTC. On the Paid plan, a trigger that runs hourly or less often gets up to 15 minutes of CPU time, against 30 seconds for more frequent ones (as of October 2026).
- Vercel: Pro or Enterprise only. Hobby is limited to one run a day.
- Jenkins: use
H * * * *(or@hourly, which means the same there) so jobs spread across the hour. See Jenkins cron.
Common mistakes
- *` 1 * * `* runs every minute between 1:00 and 1:59, not once at 1:00.
- *`0 /1 * * `* works but is just a longer way to write
0 * * * *. - Expecting UTC. Linux cron uses the machine's time zone; most cloud schedulers use UTC.
Running an AI agent every hour
Hourly suits agent checks that should catch problems the same day, like the release health check or unanswered Slack questions during working hours. The scheduled skills page shows how to run any skill on this schedule.
Questions
Is @hourly the same as 0 * * * *?
In Linux cron and Kubernetes, yes. In Jenkins, @hourly means H * * * *, a minute hashed from the job name. GitHub Actions doesn't accept @hourly at all.
What does * * * * * do compared with 0 * * * *?
* * * * * runs every minute. Putting 0 in the minute field is what limits it to once an hour, at minute 0.
How do I run a job every hour at 30 minutes past?
Use 30 * * * *. Any number from 0 to 59 in the first field picks the minute within each hour.
Why does my hourly GitHub Actions job start late?
The start of every hour is GitHub's busiest time for scheduled workflows, so runs can be delayed or dropped. Pick an odd minute such as 17 * * * *.