Skip to content

Cron schedule

Cron every 10 minutes

The cron expression for every 10 minutes is */10 * * * *. It runs at minutes 0, 10, 20, 30, 40 and 50 of every hour, 144 times a day.

Every 10 minutes
Expression*/10 * * * *
Runs144 times a day
systemd OnCalendar*:0/10

How it works

*/10 steps through the minute field from 0 in increments of 10, which gives six values per hour. Written out as a list it’s 0,10,20,30,40,50 * * * *, and the two forms are interchangeable.

Ten minutes works cleanly because 10 divides 60. The step restarts at 0 every hour, so the last run of one hour (:50) and the first of the next (:00) are 10 minutes apart, same as every other pair.

That property is what breaks for intervals that don’t divide 60, and it’s the most common cron misunderstanding after time zones. The pitfalls below show what */7 actually does.

Field-by-field breakdown
FieldValueMeaning
Minute*/10every 10 minutes: 0, 10, 20, 30, 40, 50
Hour*every hour
Day of month*every day of the month
Month*every month
Day of week*every day of the week

Next runs

Scheduler clock

As on GitHub Actions without timezone, Vercel, Cloudflare and Kubernetes with timeZone "Etc/UTC".

Next run times, computed in your browser from the current time
RunYour timeUTC
1Calculating… 
2  
3  
4  
5  

Ready-to-paste versions

The same schedule for each scheduler, with what differs on each one.

crontab (Linux, macOS, BSD)

crontab -e
# m h dom mon dow  command
*/10 * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1

# Same, but skip a run while the previous one is still going:
*/10 * * * * flock -n /tmp/job.lock /usr/local/bin/job.sh
  • cron uses the server’s time zone. On cronie (Fedora, RHEL), a CRON_TZ=Europe/London line above the entry changes the zone for the entries below it.

GitHub Actions

.github/workflows/scheduled.yml
on:
  schedule:
    - cron: '*/10 * * * *'
  workflow_dispatch: {}
  • Runs in UTC unless you set timezone, and only on the default branch. GitHub’s docs warn that scheduled runs can be delayed at busy times and that schedules in public repositories are disabled after 60 days without activity.

Kubernetes CronJob

cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: scheduled-job
spec:
  schedule: "*/10 * * * *"
  timeZone: "Etc/UTC"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: job
              image: busybox:1.36
              command: ["/bin/sh", "-c", "date; echo running"]
  • spec.timeZone is stable since Kubernetes 1.27; without it, the kube-controller-manager’s zone applies. concurrencyPolicy: Forbid skips a run while the previous Job is still active.

Vercel Cron Jobs

vercel.json
{
  "crons": [
    { "path": "/api/cron", "schedule": "*/10 * * * *" }
  ]
}
  • Vercel always uses UTC, doesn’t accept names like MON or JAN, and won’t let you set both day of month and day of week.
  • This runs more than once a day, so it needs a Pro or Enterprise plan. Per Vercel’s docs, a Hobby deployment with an expression like this fails.

Cloudflare Workers

wrangler.toml
[triggers]
crons = ["*/10 * * * *"]
  • Cron Triggers run on UTC. Changes can take up to 15 minutes to propagate across Cloudflare’s network.

node-cron (Node.js)

scheduler.js
import cron from 'node-cron';

// 6 fields: the first one (seconds) is optional
cron.schedule('0 */10 * * * *', async () => {
  await runJob();
}, { timezone: 'UTC', noOverlap: true });
  • The schedule lives inside the Node process: if it’s down, nothing runs, and three replicas run the job three times. noOverlap skips a tick while the previous run is still going.

systemd timer

job.timer + job.service
# /etc/systemd/system/job.timer
[Unit]
Description=Run job.service every 10 minutes

[Timer]
OnCalendar=*:0/10

[Install]
WantedBy=timers.target

# /etc/systemd/system/job.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/job.sh

# systemctl daemon-reload && systemctl enable --now job.timer
  • Check it with systemd-analyze calendar '*:0/10', which prints the normalized form and the next elapse. AccuracySec defaults to 1min, so the start can drift by up to a minute.

Spring @Scheduled and Quartz

Java
@Scheduled(cron = "0 */10 * * * *", zone = "UTC")
public void runJob() {
    // ...
}

// Quartz CronTrigger:
CronScheduleBuilder.cronSchedule("0 0/10 * * * ?")
  • In Spring, the first of the 6 fields is seconds; the rest follow standard cron (0 or 7 = Sunday).
  • In Quartz, one of the two day fields must be ?, so the day-of-week field gets it.

Pitfalls

Steps that don’t divide 60 leave a short gap

*/7 * * * * runs at 0, 7, 14, …, 49, 56 and then 0 again: the gap across the hour is 4 minutes, not 7. */25 runs at 0, 25, 50, then 0, a 10-minute gap. Steps only repeat within the field. For a true fixed interval, crontab(5) suggests running every minute and testing the epoch: [ $(( $(date +\%s) / 60 \% 7 )) -eq 0 ] && job.sh.

Staggering several 10-minute jobs

Two jobs on */10 start together. Give each its own offset with a ranged step: 3-59/10 runs at 3, 13, 23, …, 53 and 7-59/10 at 7, 17, …, 57.

0/10 isn’t portable

GitHub Actions, Quartz and most libraries read 0/10 as “from 0, every 10”. cronie rejects a step after a single number and wants 0-59/10 or */10. Stick with */10.

Frequently asked questions

What is the cron expression for every 10 minutes?
*/10 * * * *, which runs at minutes 0, 10, 20, 30, 40 and 50 of every hour. The list form 0,10,20,30,40,50 * * * * is equivalent.
How do I run a cron job every 10 minutes between 9 AM and 5 PM?
*/10 9-16 * * * runs from 09:00 to 16:50. Use 9-17 if you also want 17:00 to 17:50.
Why does */7 not run exactly every 7 minutes?
The step restarts at 0 every hour. */7 matches 0, 7, …, 56, so after 56 the next match is 0 of the next hour, only 4 minutes later.
What is the systemd OnCalendar for every 10 minutes?
OnCalendar=*:0/10, which systemd-analyze calendar normalizes to *-*-* *:00/10:00.

Last reviewed by Arielton Oberek.