The expression
0 * * * * /path/to/your/script.sh
Or use the macro shorthand, which works on most modern systems:
@hourly /path/to/your/script.sh
They're identical — @hourly expands to 0 * * * *.
Variations
| Expression | Meaning |
|---|---|
0 * * * * | Every hour at :00 |
30 * * * * | Every hour at :30 |
0 */2 * * * | Every 2 hours (0, 2, 4, 6, …) |
0 */3 * * * | Every 3 hours (0, 3, 6, 9, …) |
0 9-17 * * * | Every hour from 9 AM to 5 PM |
0 9-17 * * 1-5 | Every hour during business hours, weekdays only |
Platform-specific examples
Linux crontab
@hourly /usr/local/bin/refresh-cache.sh
AWS EventBridge
AWS doesn't support macros. Use the explicit form:
cron(0 * ? * * *)
GitHub Actions
on:
schedule:
- cron: '0 * * * *'
Kubernetes CronJob
schedule: "0 * * * *"
Common mistakes
Don't use * * * * * — that fires every minute, not every hour. The minute field must be 0 (or a specific minute) for hourly cadence.
Be careful with */2 in the hour field. 0 */2 * * * fires at midnight, 2 AM, 4 AM, ... 10 PM — that's a 23-hour gap at midnight on month boundaries because the count resets. Usually fine; just be aware.
Distributing load across multiple servers
If 100 servers all run @hourly, they all fire at :00 — which can overwhelm shared backends. Two fixes:
- Stagger by minute: server 1 uses
3 * * * *, server 2 uses7 * * * *, etc. - Use Jenkins'
Hsyntax (Jenkins-only) which automatically hashes the offset per job.