Cron Every 30 Seconds: How to Run a Job Twice a Minute

Standard cron can't run every 30 seconds. Learn the sleep-loop crontab workaround and systemd timer alternative for 30-second schedules.

Cron Expression

* * * * *

Standard cron cannot run more often than once per minute. This every-minute entry launches a wrapper that runs your job at :00 and :30 — see the workarounds below.

Expression Breakdown

*
Minute
(0-59)
*
Hour
(0-23)
*
Day
(1-31)
*
Month
(1-12)
*
Weekday
(0-6)
Field Value Meaning
Minute * Any minute
Hour * Any hour
Day of Month * Any day
Month * Any month
Day of Week * Any day of the week

You want to run a job every 30 seconds — but here’s the catch: standard cron only supports minute-level resolution. There is no 5-field cron expression that fires twice a minute, and any site showing you one is wrong. The smallest unit in the 5 fields is the minute.

The good news: there are two well-established workarounds.

Workaround 1: Every-Minute Entry + Sleep Loop

Schedule a wrapper every minute, and have it run your job at second :00 and again at :30:

* * * * * /path/to/every-30s.sh

With every-30s.sh:

#!/bin/bash
# Runs the job at :00 and :30 of every minute
/path/to/your/job.sh &
sleep 30
/path/to/your/job.sh

Each minute, cron starts the wrapper; it fires the job immediately, sleeps 30 seconds, and fires it once more — 2 runs per minute, at :00 and :30.

An equivalent single-line crontab version (no wrapper file needed):

* * * * * /path/to/job.sh
* * * * * sleep 30; /path/to/job.sh

The first line runs at :00, the second at :30.

Workaround 2: systemd Timer

On systemd-based Linux, timers support sub-minute intervals natively and handle logging and overlap for you. Create myjob.timer:

[Unit]
Description=Run myjob every 30 seconds

[Timer]
OnBootSec=30
OnUnitActiveSec=30
AccuracySec=1s

[Install]
WantedBy=timers.target

Pair it with a myjob.service unit that runs your script, then systemctl enable --now myjob.timer.

Should You Even Do This?

A 30-second cron cadence is sometimes a design smell. If you’re polling a database table or an API this frequently, consider an event-driven alternative: a message queue, LISTEN/NOTIFY in PostgreSQL, webhooks, or a long-running daemon with its own scheduler. Cron gives no overlap protection — if a run takes longer than 30 seconds, add a lock (flock -n /tmp/job.lock ...) to prevent stacking.

How to Use

  1. Copy the every-minute expression above into your crontab (crontab -e)
  2. Point it at a wrapper script using the sleep pattern shown
  3. Make the wrapper executable: chmod +x every-30s.sh
  4. Watch it work: grep CRON /var/log/syslog