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 platform-specific guides — the 6-field AWS form with ? and IaC snippets, or the Kubernetes manifest with timeZone and concurrencyPolicy — see the AWS EventBridge cron generator and the Kubernetes CronJob schedule generator.
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 not1 * * * *? - 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
@hourlymean and where does it work? @hourlyis a Vixie cron shortcut for0 * * * *. 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, AWS EventBridge and Quartz — with a human-readable description and the next 5 run times.
Open the Cron Expression Builder →Related
Cron expression for every Monday
The cron expression 0 9 * * 1 runs every Monday at 9 AM. Monday is 1 in both Unix and AWS — one of the few days where the numbering aligns across all schedulers.
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.
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 the last day of the month
AWS EventBridge supports cron(0 0 L * ? *). Unix cron has no L — use 0 0 28-31 * * with a date -d tomorrow test in the command.
Quartz cron expression generator (7-field syntax)
Build a 7-field Quartz cron expression (seconds, minutes, hours, dom, month, dow, year) with the ? rule and L, W, # operators — for Spring @Scheduled and standalone Quartz.