cronuru
Pattern

Every 30 Seconds

*/30 * * * * *
0/30 * * * * ?

Runs every 30 seconds (twice a minute). Requires a seconds-aware dialect — Spring or Quartz — because standard Unix cron is minute-precision only.

Use in your stack

# Two entries, offset by half a minute. At 30s this is the one
# interval where the crontab workaround stays genuinely tidy.
* * * * * flock -n /tmp/heartbeat.lock /usr/local/bin/heartbeat.sh
* * * * * sleep 30; flock -n /tmp/heartbeat.lock /usr/local/bin/heartbeat.sh

# Or a systemd timer — /etc/systemd/system/heartbeat.timer
# AccuracySec is required; the 1min default would coalesce both
# firings into a single per-minute run.
#   [Timer]
#   OnCalendar=*-*-* *:*:00/30
#   AccuracySec=1s
{
  "schedule": {
    "cron": "0/30 * * * * ?",
    "timezone": "UTC"
  }
}
// 6-field: second minute hour day-of-month month day-of-week
@Scheduled(cron = "*/30 * * * * *")
public void everyThirtySeconds() {
    // ...
}

// Simpler for pure intervals:
@Scheduled(fixedRate = 30000) // milliseconds
public void everyThirtySecondsFixedRate() {
    // ...
}

Next runs

Pick a timezone to see when this expression fires next.

Next 10 runs
  1. 012026-08-19T14:17:30.000Z
  2. 022026-08-19T14:18:00.000Z
  3. 032026-08-19T14:18:30.000Z
  4. 042026-08-19T14:19:00.000Z
  5. 052026-08-19T14:19:30.000Z
  6. 062026-08-19T14:20:00.000Z
  7. 072026-08-19T14:20:30.000Z
  8. 082026-08-19T14:21:00.000Z
  9. 092026-08-19T14:21:30.000Z
  10. 102026-08-19T14:22:00.000Z

Variations

*/5 * * * * *

Every 5 seconds

*/10 * * * * *

Every 10 seconds

*/15 * * * * *

Every 15 seconds

*/20 * * * * *

Every 20 seconds

Common use cases

  • Polling a queue or inbox twice a minute for lower latency than a 1-minute cron.
  • Refreshing a cache or health status on a 30-second heartbeat.
  • Emitting a keep-alive or liveness ping to a monitoring system.
  • Flushing a metrics buffer downstream at a steady twice-per-minute rate.

Gotchas

  • **Unix crontab cannot do this in one line.** The 5-field format has no seconds field; its minimum interval is one minute. Two entries — one plain, one offset with `sleep 30` — is the standard workaround, and at this interval it's the tidiest it ever gets. See the Linux tab above.
  • **If you reach for a systemd timer, set `AccuracySec=1s`.** It defaults to **1 minute**, so `OnCalendar=*-*-* *:*:00/30` alone lets systemd coalesce both firings into one per minute. The unit looks right and runs half as often as intended — this is the most common reason a sub-minute timer quietly misbehaves.
  • In Spring, `*/30 * * * * *` is the 6-field form (seconds first) — not Unix's `*/30 * * * *`, which means every 30 *minutes*.
  • In Quartz, use `0/30 * * * * ?` — `0/30` in the seconds field means "from second 0, every 30 seconds" (so it fires at :00 and :30 of each minute), and `?` fills the unused day-of-week field.
  • `@Scheduled(fixedRate = 30000)` (Spring) or `tokio::time::interval` (Rust) expresses the same interval without a cron parser and is often the simpler choice.
  • If a run can take longer than 30 seconds, prefer `fixedDelay` or an in-flight guard so runs don't overlap.

Unix cron is minute-precision — five fields, no seconds — so “every 30 seconds” can’t be written as a single crontab line.

On Linux, without changing schedulers

Thirty seconds is the friendliest case for the sleep-offset workaround: just two entries, one offset by half a minute (full block in the Linux tab above). Every tighter interval multiplies the line count — 20s needs three, 15s four, 10s six, 5s twelve.

It’s still approximate. sleep 30 starts when cron forks the job rather than at the top of the minute, so the second copy drifts under load; flock -n stops a slow run from stacking on the next one.

A systemd timer is the better answer if the box has systemd:

[Timer]
OnCalendar=*-*-* *:*:00/30
AccuracySec=1s

AccuracySec is load-bearing. It defaults to 1 minute, so without it systemd may coalesce both firings into a single per-minute run — the unit reads correctly and fires half as often as you asked. See systemd timers.

Or use a dialect that has seconds

For a pure interval, @Scheduled(fixedRate = 30000) or tokio::time::interval(Duration::from_secs(30)) says “every 30 seconds” without a cron parser.

This is the most-requested sub-minute interval — sub-minute scheduling covers the per-runtime support matrix and the crontab sleep 30 workaround in full.

Want an interval that doesn’t divide 60? See every 45 seconds for the non-divisor trap and its four-entry fix.

Frequently asked questions

What is the cron expression for every 30 seconds?
In a seconds-aware dialect, every 30 seconds is `*/30 * * * * *` (Spring) or `0/30 * * * * ?` (Quartz), firing at :00 and :30 of each minute. Standard Unix/crontab cannot do it — with no seconds field, its finest granularity is one minute.
How do I run a cron job every 30 seconds on Linux?
Plain crontab can't schedule sub-minute, but two offset lines get you there: `* * * * * /usr/local/bin/job.sh` and `* * * * * sleep 30; /usr/local/bin/job.sh`. Wrap both in `flock -n` so a run that overruns 30 seconds is skipped rather than stacked. The cleaner option is a systemd timer with `OnCalendar=*-*-* *:*:00/30` **and `AccuracySec=1s`** — `AccuracySec` defaults to 1 minute, and without lowering it systemd coalesces both firings into a single per-minute run.
Why doesn't `*/30 * * * *` run every 30 seconds?
`*/30 * * * *` is a 5-field Unix expression whose first field is minutes, so it runs every 30 *minutes* (at :00 and :30 of each hour). Unix cron has no seconds field. Every 30 seconds requires a 6-field dialect where the first field is seconds — Spring (`*/30 * * * * *`) or Quartz (`0/30 * * * * ?`).
How do I run something every 30 seconds in Spring Boot?
Use `@Scheduled(cron = "*/30 * * * * *")`, or more simply `@Scheduled(fixedRate = 30000)` (milliseconds). Use `fixedDelay = 30000` if each run should wait for the previous one to finish before the timer restarts.

More seconds schedules

Other patterns on the same cadence — or browse every schedule.