DEVESSENTIALS

15 * * * * — What does this cron expression mean?

15 * * * * is an hourly job shifted to quarter past. It is easily misread as “every 15 minutes”, which is */15 * * * *. The difference is a single slash and a factor of four in run count. Offsetting an hourly job from :00 is a deliberate, good practice: Debian's own /etc/crontab runs cron.hourly at minute 17 for the same reason.

In plain English

15 * * * *

Run the job once every hour at 15 minutes past the hour: 00:15, 01:15, 02:15 … 23:15.

Frequency: 1 run per hour, 24 per day. cronstrue reads it as “At 15 minutes past the hour”.

Open 15 * * * * in the Cron Builder

Field-by-field breakdown

15

Minute

0–59

*

Hour

0–23

*

Day of month

1–31

*

Month

1–12

*

Day of week

0–6

  • Minute15 — only at minute 15. A plain number, not a step, so it matches once per hour.
  • Hour* — every hour, 0 through 23.
  • Day of month* — every day of the month.
  • Month* — every month.
  • Day of week* — every day of the week.

Next run times

Example: next 5 runs

Example: if it is Monday, 5 Jan 2026, 09:07 UTC, the next runs of 15 * * * * (UTC) are:

  1. #1Mon, 5 Jan 2026, 09:15 UTC
  2. #2Mon, 5 Jan 2026, 10:15 UTC
  3. #3Mon, 5 Jan 2026, 11:15 UTC
  4. #4Mon, 5 Jan 2026, 12:15 UTC
  5. #5Mon, 5 Jan 2026, 13:15 UTC

Live times from your current clock replace this example once the page loads. Cron uses the scheduler's timezone; most cloud servers, GitHub Actions and AWS EventBridge rules use UTC.

15 * * * * in Quartz, AWS, GitHub Actions, Kubernetes and systemd

Crontab (Linux / macOS)

15 * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1

Standard 5-field syntax used by Vixie cron, cronie, busybox crond and most libraries (node-cron, APScheduler, robfig/cron).

Quartz (6 and 7 fields)

0 15 * * * ?
0 15 * * * ? *

# Spring @Scheduled
@Scheduled(cron = "0 15 * * * *")

Second 0, minute 15, every hour. Compare with every 15 minutes in Quartz, which is 0 0/15 * * * ?.

AWS EventBridge

cron(15 * * * ? *)

Runs at :15 past every hour UTC. There is no rate() equivalent, since rate(1 hour) cannot choose the minute.

GitHub Actions

on:
  schedule:
    # At minute 15 of every hour, evaluated in UTC
    - cron: '15 * * * *'

A good choice for hourly workflows: avoiding :00 is exactly what GitHub recommends to reduce delays.

Kubernetes CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: at-minute-15-every-hour
spec:
  schedule: "15 * * * *"
  timeZone: "Etc/UTC"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: job
              image: alpine:3.20
              command: ["/bin/sh", "-c", "echo running"]

Same as any hourly Job: Forbid overlaps and give it a 10-minute window to start.

systemd timer

# /etc/systemd/system/myjob.timer
[Unit]
Description=At minute 15 of every hour

[Timer]
OnCalendar=*-*-* *:15:00
Persistent=true

[Install]
WantedBy=timers.target

Shorter form: *:15. Verify with systemd-analyze calendar '*:15'.

When to use at minute 15 of every hour

  • Hourly jobs that must run after another job scheduled at :00 has finished.
  • Processing the previous hour's log file once it has been rotated at the top of the hour.
  • Spreading several hourly jobs across the hour (:05, :15, :35) instead of stacking them on :00.
  • Hourly syncs against APIs that are overloaded at the top of the hour.

Common pitfalls with 15 * * * *

15 is not */15

15 * * * * runs 24 times a day. */15 * * * * runs 96 times a day, at :00, :15, :30 and :45. Check that the schedule matches the ticket, and look at the next run times: if they are an hour apart, you have the plain 15.

15 * * * *     # 00:15, 01:15, 02:15 … (hourly)
*/15 * * * *   # 00:00, 00:15, 00:30, 00:45 … (every 15 min)

Fixed offsets are not dependencies

Scheduling a job at :15 because the :00 job “usually finishes in 10 minutes” works until the day it takes 16. If the second job depends on the first, chain them in one script (job1 && job2) or have the first job trigger the second.

0 * * * * /usr/local/bin/export.sh && /usr/local/bin/import.sh

15 * is not 15 minutes after start

The first run after you install the crontab is at the next :15, which might be one minute or 59 minutes away. If you need a delay relative to boot or deploy, use a systemd timer with OnBootSec= or OnActiveSec=.

Related cron expressions

Need a different schedule? Paste 15 * * * * into the Cron Builder and edit it, browse all cron expressions, read the cron syntax guide or copy from the cron examples list.

Frequently Asked Questions

What does 15 * * * * mean in cron?▾

Once an hour at minute 15, so at 00:15, 01:15, 02:15 and so on, 24 times a day. It does not mean every 15 minutes; that is */15 * * * *.

What is the difference between 15 * * * * and */15 * * * *?▾

15 * * * * runs once an hour at quarter past (24 runs a day). */15 * * * * runs every 15 minutes at :00, :15, :30 and :45 (96 runs a day). The slash turns a single value into a step.

How do I write 15 * * * * for AWS EventBridge?▾

cron(15 * * * ? *). EventBridge adds a year field at the end and needs ? in one of the day fields. It runs at 15 minutes past every hour in UTC.