Cron every hour
Expression: 0 * * * * — At the start of every hour.
At the start of every hour
Next 5 runs in UTC, from 1 Jan 2026 (example)
When to use it
An hourly schedule needs a fixed minute — 0 means the top of the hour, so the job runs 24 times a day at 00:00, 01:00 and so on. Writing an asterisk in the minute field is a classic mistake: the line then runs sixty times within every hour instead of once. Hourly is a good default for log rotation, sitemap regeneration, digest emails for active users and pulling data from partners who publish files on the hour. Because hourly work accumulates quietly, keep an eye on duration: a script that grows from two minutes to forty as data increases will start overlapping long before anyone notices.
Field by field
| Field | Value | Meaning |
|---|---|---|
| Minute | 0 | only 0 |
| Hour | * | every hour |
| Day of the month | * | every day of the month |
| Month | * | every month |
| Day of the week | * | every day of the week |
Real-world example
17 * * * * /usr/local/bin/rotate-logs --keep 48
Rotates logs once an hour at minute 17, away from the crowded top of the hour, and keeps the last two days of files.
Variants
| Expression | Meaning |
|---|---|
@hourly | At the start of every hour — shorthand supported by Vixie cron, cronie and most libraries |
17 * * * * | At minute 17 past every hour — every hour at minute 17 |
0 */2 * * * | Every 2 hours, at minute 0 — every two hours, at even hours only |
Pitfalls
- Container images built from scratch often lack a cron daemon entirely; prefer the orchestrator's native scheduler instead of installing crond inside an application image.
- * * * * * runs every minute; an hourly job must fix the minute, as in 0 * * * *.
- On the night clocks go back, a local-time hourly job may run twice in the repeated hour; when clocks go forward, one run is skipped. Run servers in UTC to avoid both.
- If the job usually takes 50 minutes, a slow run will overlap the next one. Add a lock or move to every two hours.
Questions
Why does my hourly job print nothing in the terminal?
Cron runs without a terminal. Standard output is e-mailed to the crontab owner when a mail transfer agent exists, otherwise discarded. Redirect stdout and stderr to a file to keep a history you can read.
What is the difference between 0 * * * * and @hourly?
None in Vixie cron and cronie: @hourly is expanded to 0 * * * *. Some hosted schedulers do not support shorthands, so the full form is more portable.
How do I run hourly only at night?
Restrict the hour field with a range or list, for example 0 0-6 * * * for every hour from midnight to 06:00, or 0 22,23,0-5 * * * across midnight.
The same schedule elsewhere
- GitHub Actions:
on: schedule: - cron: '0 * * * *'. Always UTC, and runs can start several minutes late when runners are busy. - Kubernetes CronJob:
schedule: "0 * * * *"; setconcurrencyPolicy: Forbidto prevent overlapping pods andtimeZoneif you need local time. - Cloudflare Workers:
crons = ["0 * * * *"]under[triggers]in wrangler.toml, evaluated in UTC.
Before you deploy
Use absolute paths, because cron starts commands with a minimal PATH and without your shell profile. Make the job idempotent so a late or repeated run does no harm, log its exit code, and let a dead-man's-switch monitor alert you when an expected run never happens.