Cron every quarter

The cron expression for every quarter is:

0 0 1 */3 *

Runs four times a year at 00:00 on the first day of January, April, July and October.

4 times a year
Standard 5-field cron

Next 10 runs

For 0 0 1 */3 *, in the timezone you pick. Cron uses the server's timezone.

Times in UTC as of the last site update. They refresh when the page loads in a browser.

#Date and timeWhen
1Jan 1, 2027, 00:00Friday
2Apr 1, 2027, 00:00Thursday
3Jul 1, 2027, 00:00Thursday
4Oct 1, 2027, 00:00Friday
5Jan 1, 2028, 00:00Saturday
6Apr 1, 2028, 00:00Saturday
7Jul 1, 2028, 00:00Saturday
8Oct 1, 2028, 00:00Sunday
9Jan 1, 2029, 00:00Monday
10Apr 1, 2029, 00:00Sunday

How to read 0 0 1 */3 *

0 0 1 sets midnight on the 1st. */3 in the month field takes every third month, starting at 1 (January). It is the same as 0 0 1 1,4,7,10 *.

FieldValueMeaningAllowed
Minute0At the top of the hour0-59
Hour0At 12:00 AM0-23
Day of month1On the 1st1-31
Month*/3In January, April, July, October1-12 or jan-dec
Weekday*Every day of week0-7 or sun-sat

Watch out for

  • Months run from 1 to 12, so */3 starts at January. For the last month of each quarter (March, June, September and December), use 0 0 1 3,6,9,12 *.
  • A job that runs four times a year is easy to forget. Monitor it, so a missed run is noticed in days, not months.

Often used for: Quarterly reports, access reviews and key rotations.

Use it in

crontab

0 0 1 */3 * /path/to/your-script.sh

Edit with crontab -e. Runs in the server's timezone.

Kubernetes CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-job
spec:
  schedule: "0 0 1 */3 *"
  timeZone: "Etc/UTC"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: my-job
              image: busybox:1.36
              command: ["sh", "-c", "date"]

Without timeZone, the schedule follows the timezone of the kube-controller-manager.

GitHub Actions

on:
  schedule:
    - cron: '0 0 1 */3 *'
      timezone: "Etc/UTC"
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./your-script.sh

Without timezone, GitHub runs schedules in UTC. It runs them at most every 5 minutes, and a run can start late when GitHub is busy.

All cron schedules

Cron does not tell you when a job stops

Know when a job on this schedule does not run.

Your job pings Drumbeats when it finishes. If a ping does not arrive on schedule, you get an alert. No SDK, free for up to 50 monitors.

Free for up to 50 monitors · Setup in 60 seconds · No credit card required