cronuru
Pattern

Every 20 Minutes

*/20 * * * *
0 */20 * * * ?
*/20 * * * *
*/20 * * * ? *
0 */20 * * * *
*/20 * * * *

Runs every 20 minutes — at :00, :20, :40 of every hour, every day. 3 invocations per hour.

Use in your stack

# Run every 20 minutes
*/20 * * * * /usr/local/bin/poll.sh
{ "cron": "0 */20 * * * ?", "timezone": "UTC" }
apiVersion: batch/v1
kind: CronJob
metadata:
  name: every-20-min
spec:
  schedule: "*/20 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: job
            image: my-image:latest
          restartPolicy: OnFailure
cron(*/20 * * * ? *)
@Scheduled(cron = "0 */20 * * * *")
public void every20Minutes() { /* ... */ }
on:
  schedule:
    - cron: '*/20 * * * *'

Next runs

Pick a timezone to see when this expression fires next.

Next 10 runs
  1. 012026-07-13T16:20:00.000Z
  2. 022026-07-13T16:40:00.000Z
  3. 032026-07-13T17:00:00.000Z
  4. 042026-07-13T17:20:00.000Z
  5. 052026-07-13T17:40:00.000Z
  6. 062026-07-13T18:00:00.000Z
  7. 072026-07-13T18:20:00.000Z
  8. 082026-07-13T18:40:00.000Z
  9. 092026-07-13T19:00:00.000Z
  10. 102026-07-13T19:20:00.000Z

Variations

*/15 * * * *

Every 15 minutes

*/10 * * * *

Every 10 minutes

*/30 * * * *

Every 30 minutes

*/5 * * * *

Every 5 minutes

Common use cases

  • Polling an external API or feed that updates a few times an hour.
  • Aggregating metrics into a time-series store on 20-minute buckets.
  • Rebuilding a cache or precomputed view that tolerates ~20 minutes of staleness.
  • Resyncing data from a moderately active upstream system.

Gotchas

  • `*/20` fires at :00, :20, :40 and then resets at the top of the hour — spacing stays an even 20 minutes because 60 divides evenly by 20.
  • Aligns to clock 20-minute boundaries, not to when the job was added.
  • AWS EventBridge: `*/20 * * * ? *` (6 fields, `?` placeholder). Quartz: `0 */20 * * * ?` (seconds field first).

*/20 * * * * runs three times an hour — at :00, :20, and :40. It sits between every 15 minutes and every 30 minutes, and it’s a comfortable cadence for polling and aggregation work that should stay current without hammering an upstream system.

The step syntax */20 expands to 0,20,40. Because 60 divides evenly by 20, there’s no leftover when the minute counter resets at the top of the hour, so every gap is exactly 20 minutes. That clean division is why this interval works in plain cron while awkward ones like “every 45 minutes” don’t — those leave a remainder and drift across the hour boundary. For faster cadences see every 10 minutes or every 5 minutes; for slower, every 30 minutes.

Frequently asked questions

What does `*/20 * * * *` mean?
The minute field `*/20` means "every 20th minute starting from 0," and the remaining fields are wildcards. So the job runs at :00, :20, and :40 of every hour, every day — 3 times per hour, 72 times per day.
Is `*/20 * * * *` the same as `0,20,40 * * * *`?
Yes — they're identical. `*/20` is shorthand for the explicit list `0,20,40`. Every cron dialect accepts both; the step form is just more compact.
Why doesn't every 20 minutes drift across the hour?
Because 60 is evenly divisible by 20. The runs land at :00, :20, :40 and the counter resets at the top of each hour with no leftover, so the spacing stays a clean 20 minutes. Intervals that don't divide 60 — like 45 minutes — do drift and can't be expressed cleanly in standard cron.
How do I run every 20 minutes in Spring Boot?
Use the 6-field form with a leading seconds field: `@Scheduled(cron = "0 */20 * * * *")`. For a pure interval you can also use `@Scheduled(fixedRate = 1200000)` — 20 minutes in milliseconds — which doesn't need a cron parser at all.

Browse all cron patterns

Every schedule Cronuru documents, with its expression and code snippets for six dialects.