Run scheduled jobs every 5, 10 or 30 seconds

Choose a timer or a carefully bounded loop for sub-minute work, with explicit overlap and timing behavior.

Best practices
Illustration of scheduled jobs, logs and Linux operations

Traditional system cron has minute-level scheduling. A sixth “seconds” field copied from Quartz or another application scheduler will not make a system crontab run every few seconds. For ongoing sub-minute work, use a suitable timer or a supervised process.

Prefer a timer with explicit semantics

On systemd, a oneshot service can run a command under a dedicated account:

# /etc/systemd/system/myjob.service
[Service]
Type=oneshot
User=appuser
ExecStart=/opt/jobs/task.sh

This timer waits ten seconds after the service becomes inactive before triggering it again:

# /etc/systemd/system/myjob.timer
[Timer]
OnBootSec=1min
OnUnitInactiveSec=10s
AccuracySec=1s

[Install]
WantedBy=timers.target

Install both units and enable the timer:

sudo systemctl daemon-reload
sudo systemctl enable --now myjob.timer
systemctl list-timers myjob.timer
journalctl -u myjob.service

Change 10s to 5s or 30s as needed. The start-to-start interval includes the job's runtime; this is intentionally a delay after completion, not a fixed wall-clock cadence. AccuracySec narrows systemd's coalescing window but does not provide real-time execution guarantees.

OnUnitActiveSec instead measures from activation. An already active service is not started again, so a long job can change the cadence. Choose and test the timer semantics against the job's actual duration. Persistent catch-up is a calendar-timer feature, not a guarantee supplied by these monotonic intervals.

Use a cron loop only when its limits are acceptable

For a small compatibility workaround, a minute-triggered wrapper can run a foreground command a bounded number of times:

#!/bin/sh
exec 9>/var/lib/myjob/loop.lock || exit 1
/usr/bin/flock -n 9 || exit 1
attempt=0
while [ "$attempt" -lt 6 ]; do
    /opt/jobs/task.sh
    status=$?
    [ "$status" -eq 0 ] || exit "$status"
    attempt=$((attempt + 1))
    [ "$attempt" -ge 6 ] || sleep 10
done

On Linux, provision the lock directory for the account, save the wrapper, and schedule it:

* * * * * /opt/jobs/subminute-wrapper.sh

Six attempts with ten-second sleeps are only approximate. Command duration adds to the gaps; if the wrapper crosses the next minute, its lock causes the next invocation to skip. For five-second sleeps use twelve attempts; for thirty-second sleeps use two. This pattern is not an exact every-N-seconds scheduler.

Adding & to run each command in the background can create overlapping children and hide their failures. Do that only with deliberate concurrency limits and result collection, rather than using it as a general timing fix.

Consider a continuously running worker

A consumer or collector may fit a supervised service better than repeated process launches. Event-driven work may fit a queue or filesystem event mechanism. Select a restart policy that matches expected exits and failures, and make repeated work idempotent.

Record expected and actual start times, completion, and run identifiers. Guance log detection can observe collected success and error records, but a count over a window does not establish which particular execution was missed.

Common questions

Can a timer guarantee an exact five-second interval? No. Runtime, scheduling delays and load still matter. Use real-time facilities if deadlines require them.

What happens when a job exceeds the interval? It depends on your chosen policy: wait after completion, skip while active, or overlap. Make the policy explicit.

Should I combine every short task into one loop? Not automatically. Combining tasks can couple their delays and failures. Use separate supervised units or a scheduler when that gives clearer isolation.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting