CronHub

Build cron expressions visually — with a live schedule preview.

Cron Job Every Hour: Syntax and Examples

To run a cron job every hour, place 0 * * * * before the command in your user crontab. This runs at minute 0 of every hour; @hourly is a convenient equivalent on cron implementations that support shortcut strings. For fleets or busy servers, use a fixed minute offset such as 17 * * * * to avoid every job starting on the hour.

Cron expression for every hour

Use this entry to run a script at the start of every hour:

0 * * * * /usr/local/bin/hourly-task.sh

The five scheduling fields mean:

FieldValueMeaning
Minute0At minute zero
Hour*Every hour
Day of month*Every day of the month
Month*Every month
Day of week*Every day of the week

The job therefore runs at 00:00, 01:00, 02:00, and so on through 23:00 according to the cron daemon’s clock and time zone.

You can build and preview this expression once on cronhub.online before installing it. A preview is especially useful when an expression includes ranges, lists, or step values.

Is @hourly the same as 0 * * * *?

On cron implementations that support special scheduling strings, this entry also runs once per hour:

@hourly /usr/local/bin/hourly-task.sh

For the usual Vixie cron and Cronie behavior, @hourly is equivalent to running at minute 0 of every hour. It is easier to read, but the standard five-field expression is more portable across cron-like schedulers, control panels, libraries, and deployment tools.

ScheduleTypical meaningMain advantage
0 * * * *At minute 0 of every hourExplicit and broadly portable
@hourlyOnce per hour, normally on the hourShort and readable
17 * * * *At minute 17 of every hourAvoids on-the-hour contention

Use 0 * * * * when configuration portability matters. Use @hourly when you control the target system and have confirmed that its cron daemon supports shortcut strings.

Neither form means “run exactly 60 minutes after the previous execution finishes.” Cron evaluates wall-clock schedules. If you need an interval measured from task completion, a persistent worker, queue, or systemd timer may be a better fit.

Copy-and-paste hourly examples

Edit your current user’s crontab with:

/usr/bin/crontab -e

Then add one of the following entries.

Run a shell script every hour

0 * * * * /usr/local/bin/hourly-task.sh

Make sure the script is executable:

/bin/chmod +x /usr/local/bin/hourly-task.sh

The script should use absolute paths for files and important executables. Cron usually provides a smaller environment than your interactive shell.

Run a Python script every hour

0 * * * * /usr/bin/python3 /opt/reporting/hourly_report.py

Specify the interpreter explicitly rather than relying on a shell alias, activated virtual environment, or current working directory.

If the program uses a virtual environment, call that environment’s interpreter directly:

0 * * * * /opt/reporting/venv/bin/python /opt/reporting/hourly_report.py

Run a backup every hour

0 * * * * /usr/bin/tar -czf /var/backups/app-latest.tar.gz /srv/app/data

This example replaces the same archive each hour. For production backups, consider retention, incomplete archive handling, storage capacity, and whether files can change while the archive is being created.

Request an application endpoint every hour

0 * * * * /usr/bin/curl --fail --silent --show-error https://example.com/internal/hourly-task

The --fail option makes HTTP error responses produce a nonzero exit status. Protect task endpoints with appropriate authentication and do not place long-lived secrets directly in a widely readable crontab.

Run only during business hours

This entry runs at the start of each hour from 09:00 through 17:00, Monday through Friday:

0 9-17 * * 1-5 /usr/local/bin/business-hour-task.sh

Here, 9-17 selects an inclusive range of hours and 1-5 selects weekdays.

Stagger hourly jobs across a fleet

Starting every hourly task at minute 0 can create a thundering herd. Database maintenance, API calls, backups, monitoring checks, and package metadata refreshes may all compete for CPU, storage, network bandwidth, or a shared upstream service.

A simple fix is to choose a stable minute offset:

17 * * * * /usr/local/bin/hourly-task.sh

This still runs once during every clock hour, but at 00:17, 01:17, 02:17, and so on.

For multiple services, assign different offsets:

7 * * * * /usr/local/bin/sync-customers.sh
23 * * * * /usr/local/bin/build-report.sh
41 * * * * /usr/local/bin/refresh-cache.sh

For a server fleet, generate a deterministic offset from a host identifier in your configuration management system, then install that number as the minute field. Deterministic offsets remain stable across reboots and deployments, unlike a new random value generated each time configuration is applied.

Do not use */60 in the minute field to express “every 60 minutes.” The minute field only spans 0 through 59, and 0 * * * * communicates the intended hourly schedule directly.

Prevent overlapping hourly runs

If a task can take longer than an hour, a new instance may start while the previous one is still active. Overlap can duplicate work, corrupt output, or increase load.

On Linux systems with flock, use a lock file:

0 * * * * /usr/bin/flock -n /run/lock/hourly-task.lock /usr/local/bin/hourly-task.sh

The -n option exits immediately when another process holds the lock. Use a lock location writable by the account running the job. An unprivileged user may need a directory under its home or runtime directory instead of /run/lock.

If skipped executions are unacceptable, locking alone is not enough. You may need queueing, retry logic, or a scheduler that records missed and pending work.

Capture output and errors

Cron may email command output when local mail delivery is configured, but you should not assume that mail is available. Redirect standard output and standard error to a known log file:

17 * * * * /usr/local/bin/hourly-task.sh >> /var/log/hourly-task.log 2>&1

The account running the job must have permission to create or append to the file. For a user crontab, a path under the user’s home directory may be safer:

17 * * * * /usr/local/bin/hourly-task.sh >> /home/deploy/logs/hourly-task.log 2>&1

Create the directory before relying on it:

/bin/mkdir -p /home/deploy/logs

Plan for log rotation so the file does not grow indefinitely. Also make the script return a nonzero exit status when it fails, allowing monitoring systems and wrappers to detect the problem.

Cron environment and location matter

A user crontab contains five time fields followed by the command:

0 * * * * /usr/local/bin/hourly-task.sh

A system crontab such as /etc/crontab includes an additional username between the schedule and command:

0 * * * * root /usr/local/sbin/hourly-task.sh

Do not copy the root field into a user crontab opened with crontab -e. Cron will interpret it as part of the command and the job will fail.

Cron also may not load your interactive shell profile. Use absolute executable and file paths, set required environment variables deliberately, and change directories explicitly when an application expects a particular working directory:

0 * * * * cd /srv/app && /usr/bin/python3 /srv/app/tasks/hourly.py

The schedule follows the time zone used by the cron daemon unless your implementation provides and honors a separate time-zone setting. Daylight-saving transitions and clock changes can affect wall-clock scheduling, so verify time-sensitive behavior on the exact cron implementation you operate.

Verify the hourly job

After saving the crontab, list the installed entries:

/usr/bin/crontab -l

Test the underlying command manually using the same account that cron will use:

/usr/local/bin/hourly-task.sh

A successful manual run does not prove that cron has the same environment or permissions, but it catches missing files, invalid arguments, and basic execution failures. Check your system’s cron service logs and the redirected task log after the next scheduled minute.

Frequently Asked Questions

What cron expression runs at the start of every hour?

Use 0 * * * *. The zero selects minute 0, while each asterisk allows every value in the remaining hour, day, month, and weekday fields.

Is @hourly exactly the same as 0 * * * *?

On common cron implementations that support shortcut strings, @hourly runs at the beginning of each hour and is equivalent to 0 * * * *. The five-field form is preferable when you need compatibility with tools that do not recognize cron shortcuts.

How do I run a cron job hourly but not on the hour?

Choose a minute from 1 through 59, such as 17 * * * *. This runs once every hour at minute 17 and can reduce contention with other scheduled workloads.

What happens if an hourly cron job takes longer than one hour?

Cron can start another copy at the next scheduled time, even if the earlier process is still running. Use a lock such as flock, redesign the task to be safe when concurrent, or move the work to a scheduler with queueing and execution-state tracking.

Does an hourly cron job run every 60 elapsed minutes?

Not necessarily. Cron uses wall-clock times, so clock adjustments, daemon downtime, and time-zone behavior can affect execution. Use an interval-aware scheduler if you require exactly 60 elapsed minutes between runs.

Need the expression itself? Build and test any cron schedule in our free visual generator — with live upcoming-run previews in Unix and Quartz formats.

Related guides

References