How to run a cron job every 30 seconds or less
Updated 16 October 2026
A crontab line runs at most once a minute: the expression has no field for the seconds. To run a job more often, there are two ways: several runs inside each minute, from the crontab, or a systemd timer, which does have seconds.
Every 30 seconds, with two lines
* * * * * /path/to/job.sh
* * * * * sleep 30; /path/to/job.sh
The first line runs at the start of each minute, and the second waits 30 seconds before running. Cron starts both at the same time, so they don’t depend on each other.
Every 10 seconds, with a loop
* * * * * for i in 0 1 2 3 4 5; do /path/to/job.sh & sleep 10; done
The loop starts the job six times a minute, 10 seconds apart. The & starts each run without waiting for the previous one to end, so the job’s own duration isn’t added to the 10 seconds of waiting. Because of that, if a run takes longer than 10 seconds, two copies run at the same time: flock prevents it.
With a systemd timer
A systemd timer accepts seconds, and it behaves differently from the loop: a time that arrives while the service is still active doesn’t start another copy. Choose the one that fits your job: with the loop, runs can overlap; with the timer, a slow run delays the next one. Two files, /etc/systemd/system/job.service:
[Unit]
Description=Job every 10 seconds
[Service]
Type=oneshot
ExecStart=/path/to/job.sh
And /etc/systemd/system/job.timer:
[Unit]
Description=Run job.service every 10 seconds
[Timer]
OnCalendar=*:*:0/10
AccuracySec=1s
[Install]
WantedBy=timers.target
Then:
sudo systemctl daemon-reload
sudo systemctl enable --now job.timer
systemctl list-timers job.timer
-
AccuracySec=1smatters. By default, a timer can fire up to a minute after its time, to group wake-ups: for a job every 10 seconds, that’s no use. -
systemd-analyze calendar "*:*:0/10"shows the next times, to check the expression. -
The output goes to the journal:
journalctl -u job.service.
When it’s better not to schedule it
A job that has to run every second or two is usually better as a process that stays running, with a loop and its own pause, supervised by systemd. Starting a new process every few seconds also costs: the interpreter, the connections, the configuration.
If you came from Spring or Quartz, an expression with seconds, like */10 * * * * *, has no equivalent in crontab: the cron tester tells you which ones do.
Watch it by the minute
CronDrive checks the schedule by the minute. You can monitor the run of each minute, with the calls in the first of the two lines, but that doesn’t check the run in between. If you need to detect every failure or every missing run, this check by the minute isn’t enough.