How to run a cron job every 30 minutes: the */30 pattern and the business hours trap
By TechCompare · Updated · How we check
Use */30 * * * * for every 30 minutes. For business hours, give the final run its own line, because a range like 9-17 also fires at 5:30 PM.
Calculator
Next runs of */30 * * * *
Example from Mon, Nov 9, 2026 at 8:00 AM.
- Mon, Nov 9, 2026 at 8:30 AM
- Mon, Nov 9, 2026 at 9:00 AM
- Mon, Nov 9, 2026 at 9:30 AM
- Mon, Nov 9, 2026 at 10:00 AM
- Mon, Nov 9, 2026 at 10:30 AM
*/30 * * * * runs a job at minutes 0, 30 of every hour, every day. That comes to 2 runs an hour. It suits sync jobs, status checks and feed pulls that need fresh data without running every few minutes. The expression is simple, but the clock has a few traps.
How this is calculated
Each field has one job. The minute field, */30, is the only one that changes anything: the slash picks every 30th minute. The hour, day of month, month and day of week fields are all *, which means no limit on any of them. Because 30 divides 60 evenly, the gap between runs stays 30 minutes all the way around the hour. Cron reads the server's local time zone by default, so :00 and :30 follow that clock, as the cron time zone pitfalls page explains. Add your command after the five fields:
*/30 * * * * /path/to/jobThe first trap is the business hours window. The hour field matches all of hour 17, so */30 9-17 * * * also fires at 5:00 PM and 5:30 PM. That's 18 runs a day, and the last one lands at 5:30 PM, which is past a 5 PM close. For a window that ends at 5 PM, use */30 9-16 * * *, which gives 16 runs a day from 9:00 AM to 4:30 PM, and put 0 17 * * * on its own line for the 5 PM run.
Plenty of jobs start on the clock marks, like backups, log rotation and monitoring checks, so a job on :00 and :30 can land on top of them. Shift the start to avoid the crowd: 7-59/30 * * * * runs at minutes 7, 37 and still gives 48 runs a day. Any start minute from 0 to 29 keeps the same number of runs, so pick the one that suits the job.
Cron has no memory of its last run. It only checks whether the five fields match the current time (the field rules are in crontab(5)), so */30 means the marks at :00 and :30 and not 30 minutes after each run ends. If a run goes past the next mark, the next copy starts anyway, and the two can overlap. A gap measured from the end of the last run is a different scheduling model, so compare the options on the cron vs systemd timers page.
For scale, */30 * * * * gives 48 runs a day. That's fewer runs than */15 * * * *, which runs 96 times a day, so the 15 minute schedule is the busier one. It runs more often than 0 * * * *, which runs 24 times a day.
Verdict
Use */30 when nothing else on the machine fires on the marks, and move to an offset like 7-59/30 when something does. Don't count on a gap after each run, because cron only follows the clock. A job that can run past the next mark needs its own plan for overlap, because no offset fixes that.
More Cron scenarios
Related guides
Frequently asked questions
How do I run a cron job every 30 minutes?
*/30 * * * * in front of your command, such as */30 * * * * /path/to/job. The step fires the job at minutes 0, 30 of every hour, which is 48 runs a day.Is `*/30` the same as `0,30`?
*/30 is shorter, and changing it to */15 changes the schedule without rewriting a list of minutes.How do I run it every 30 minutes only from 9 AM to 5 PM?
*/30 9-16 * * *, which runs from 9:00 AM to 4:30 PM (16 runs a day), then add 0 17 * * * for the 5 PM run. Don't use 9-17, because the 5 PM hour also fires at 5:30 PM.Why shouldn't I schedule at :00 and :30?
7-59/30 * * * * runs at minutes 7, 37.Does cron wait 30 minutes after the job finishes?
Related tools
Unix Timestamp
Convert between Unix timestamps and human-readable dates.
Use toolCHMOD Configurator
Calculate Linux file permissions using checkboxes or octal numbers, then view the matching symbolic notation.
Use toolText Encoding Converter
Convert text to Base64, binary, hex, URL encoding and HTML entities, and back again.
Use tool