Cron expression for every hour
The cron expression 0 * * * * runs a job every hour on the hour — at 00:00, 01:00, 02:00 and so on through every day. Twenty-four runs per day. The leading 0 is the minute, not a counter — it means “fire at minute zero of every hour”, which gives you exactly one run per hour aligned to the wall clock.
Quick reference
| Platform | Expression |
|---|---|
| Unix / Linux crontab | 0 * * * * or @hourly |
| Kubernetes CronJob | 0 * * * * or @hourly |
| GitHub Actions | 0 * * * * |
| AWS EventBridge | cron(0 * * * ? *) |
| Quartz (Java) | 0 0 * ? * * |
@hourly is a Vixie-cron shortcut that expands to 0 * * * * — it’s accepted by Linux crontab, GitHub Actions, anacron and Kubernetes CronJob. AWS EventBridge does NOT accept it; use the explicit form there.
Why does the expression read 0 * * * *?
Cron’s first field is minute, the second is hour. 0 in the minute field means “fire when the wall-clock minute is exactly 0”. The * in the hour field means “any hour”. Combine the two: fire at minute 0 of every hour — i.e. on the hour, every hour.
A common mistake is reading 0 * * * * as “every 0 minutes” or “0 hours”. It’s neither. To run every N hours you’d write 0 */N * * * (N=2 means every other hour). To run every N minutes you’d write */N * * * *.
Variations
| Schedule | Expression |
|---|---|
| Every hour at :30 instead of :00 | 30 * * * * |
| Every hour, business hours only | 0 9-17 * * * |
| Every hour, weekdays only | 0 * * * 1-5 |
| Every hour, but not at midnight | 0 1-23 * * * |
| Every hour in AWS | cron(0 * * * ? *) |
How do I use it on each platform?
Linux crontab:
0 * * * * /usr/local/bin/sync-data
Or equivalently:
@hourly /usr/local/bin/sync-data
Kubernetes CronJob:
apiVersion: batch/v1
kind: CronJob
metadata:
name: sync-data
spec:
schedule: "0 * * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: sync
image: my-org/sync-data:1.0
restartPolicy: OnFailure
AWS EventBridge:
aws events put-rule \
--name hourly-sync \
--schedule-expression "cron(0 * * * ? *)"
EventBridge has a rate(1 hour) alternative — same effect, simpler syntax. Use cron() if you specifically need :00 alignment; rate() fires hourly from the moment the rule was created.
GitHub Actions:
on:
schedule:
- cron: '0 * * * *'
Common mistakes
Reading 0 * * * * as “every 0 minutes” and getting confused. The first field is minute. 0 in minute = “at minute zero”. Pair it with * in hour and you get “at minute zero of every hour”.
Using @hourly in AWS EventBridge. AWS rejects it. Use cron(0 * * * ? *) instead.
Confusing 0 * * * * with * 0 * * *. The latter means “every minute, but only during hour 0” — i.e. 60 runs between 00:00 and 00:59, then nothing for the rest of the day. Common typo when you misremember field order.
For other schedules see common cron schedules, or build a custom expression with the Cron Expression Builder.
Frequently asked questions
- Why is it `0 * * * *` and not `1 * * * *`?
- The first field is *minute*, not "every Nth time". `0 * * * *` means "fire at minute 0 of every hour" — so :00, :01-of-the-next-hour means the next firing is at the top of the next hour. `1 * * * *` would run at :01 of every hour, not "every 1 hour".
- What does `@hourly` mean and where does it work?
- `@hourly` is a Vixie cron shortcut for `0 * * * *`. It works in Linux crontab, anacron, GitHub Actions and Kubernetes CronJob (kube-controller-manager parses it). It does NOT work in AWS EventBridge, which only accepts the explicit 6-field form. Use the explicit form when in doubt.
- How do I run something every hour but not at :00?
- Just change the minute. `30 * * * *` runs at :30 of every hour. `15 * * * *` runs at :15. The minute field is purely the wall-clock minute, not an offset from anything.
Need a different schedule?
Build cron expressions for Unix, Kubernetes and AWS — with a human-readable description and the next 5 run times.
Open the Cron Expression Builder →Related
Cron expression for every 5 minutes
The cron expression `*/5 * * * *` runs every 5 minutes in Linux crontab, Kubernetes, GitHub Actions; `cron(*/5 * * * ? *)` in AWS EventBridge.
Cron expression for every 15 minutes
The cron expression `*/15 * * * *` runs every 15 minutes — at :00, :15, :30, :45 — across Linux, Kubernetes, GitHub Actions and AWS.
Cron expression for daily at midnight
The cron expression `0 0 * * *` runs once daily at midnight. Watch the timezone — Kubernetes < 1.25 and AWS EventBridge default to UTC, not local time.
Cron expression for every weekday
The cron expression `0 9 * * 1-5` runs at 9 AM Monday through Friday. AWS uses `cron(0 9 ? * MON-FRI *)` because day-of-week numbering differs.
Cron expression for the first of every month
The cron expression `0 0 1 * *` runs at midnight on the 1st of every month. AWS uses `cron(0 0 1 * ? *)`.
Cron expression for every Sunday
The cron expression `0 0 * * 0` runs every Sunday at midnight in Unix cron. AWS uses `cron(0 0 ? * 1 *)` because Sunday is `1` in AWS, not `0`.