*/30 * * * * runs a job twice an hour, on the hour and at half past. With a step of 30, the minute field picks 0 and 30, so 0,30 * * * * is the same schedule written out.
When it fires
Checked at 09:58 UTC, the next five runs are:
10:00 10:30 11:00 11:30 12:00
A different half hour
To run at :15 and :45 instead, list the minutes: 15,45 * * * *. To run every 30 minutes only in working hours: */30 9-17 * * 1-5, whose last run is at 17:30.
Every 30 minutes isn’t every 90
A step only counts within one field and starts again each hour, so */90 doesn’t mean “every hour and a half”. For that, list the times you want across two lines, or use a scheduler with intervals, like EventBridge’s rate() or a systemd timer’s OnUnitActiveSec=90min.
The same schedule elsewhere
- GitHub Actions:
cron: '*/30 * * * *', in UTC. - Kubernetes CronJob:
schedule: "*/30 * * * *". - AWS EventBridge:
rate(30 minutes), orcron(0/30 * * * ? *). - systemd timer:
OnCalendar=*:0/30. - Spring
@Scheduled:0 */30 * * * *.