Closest cron expression
* * * * *
Every minute. On its own, it runs 1,440 times a day, 525,600 times a year.
Cron’s smallest unit is one minute, so no cron expression runs every 30 seconds. If you need sub-minute timing regularly, a systemd timer with OnUnitActiveSec=30s or a long-running process with its own loop is a better fit than cron.
Workaround: run a job every 30 seconds
Add two crontab lines with the same every-minute schedule. The second one sleeps for 30 seconds before running, so together they fire at :00 and :30 of every minute.
* * * * * /usr/local/bin/job.sh
* * * * * sleep 30; /usr/local/bin/job.sh
The same idea works on every scheduler below: keep the base schedule and put the check at the start of the job’s command or script.
Field by field
| Field | Value | Matches |
|---|---|---|
| minute | * |
every value |
| hour | * |
every value |
| day of month | * |
every value |
| month | * |
every value |
| day of week | * |
every value |
Examples
crontab
Run crontab -e and add:
* * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1
For the exact schedule, use the workaround line above instead.
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: my-job
spec:
schedule: "* * * * *"
timeZone: "Etc/UTC" # Kubernetes 1.27+
concurrencyPolicy: Forbid # skip a run if the last one is still going
jobTemplate:
spec:
template:
spec:
containers:
- name: job
image: ghcr.io/acme/job:1.0
restartPolicy: OnFailure
GitHub Actions
on:
schedule:
- cron: '* * * * *' # UTC
GitHub Actions won’t run a schedule more often than every 5 minutes, so this workflow will run less often than the expression says. Scheduled runs can also start late when GitHub is busy.
systemd timer
# /etc/systemd/system/job.timer
[Unit]
Description=Run job.service every 30 seconds
[Timer]
OnCalendar=*-*-* *:*:00
Persistent=true
[Install]
WantedBy=timers.target
Enable it with systemctl enable --now job.timer, and check the next runs with
systemd-analyze calendar "*-*-* *:*:00". Persistent=true runs a missed job after
downtime, which cron can’t do.
AWS EventBridge
cron(* * * * ? *)
EventBridge cron has six fields (the last is the year), uses ? in either the day-of-month or the
day-of-week field, and numbers weekdays from 1 (Sunday) to 7. Rules run in UTC; EventBridge Scheduler also
accepts a time zone.
Similar schedules: every few minutes
-
Every minute:
* * * * * -
Every 2 minutes:
*/2 * * * * -
Every 3 minutes:
*/3 * * * * -
Every 5 minutes:
*/5 * * * * -
Every 10 minutes:
*/10 * * * * -
Every 15 minutes:
*/15 * * * * -
Every 20 minutes:
*/20 * * * * -
Every 30 minutes:
*/30 * * * * -
Every 45 minutes:
*/45 * * * * -
Every 5 minutes during business hours:
*/5 9-17 * * 1-5
Have a different schedule? Paste any expression into the Cron Expression Generator, or browse all cron examples.
Sources
- POSIX: crontab
- crontab(5) manual page
- Kubernetes docs: CronJob
- GitHub Actions docs: schedule event
- systemd.time(7): calendar events
- AWS docs: EventBridge Scheduler cron expressions
Spotted a mistake? Email hello@devtoolsmith.com and we’ll fix it.
Frequently asked questions
How do I run a cron job every 30 seconds?
No single standard cron expression does this exactly. Cron’s smallest unit is one minute, so no cron expression runs every 30 seconds. If you need sub-minute timing regularly, a systemd timer with OnUnitActiveSec=30s or a long-running process with its own loop is a better fit than cron. Add two crontab lines with the same every-minute schedule. The second one sleeps for 30 seconds before running, so together they fire at :00 and :30 of every minute. * * * * * /usr/local/bin/job.sh * * * * * sleep 30; /usr/local/bin/job.sh