HTTPfy

First day of every month

At 00:00 on day 1 of every month: 12 runs a year.

Shorthand in Vixie cron, cronie and Kubernetes: @monthly

12runs in the next 365 days
28 days / 31 daysshortest / longest gap between runs
00:00next run, Tue 01 Dec UTC

What it is used for

Monthly billing and invoicing, usage reports for the previous month, archiving last month's logs.

Field by field

FieldValueMatches
Minute00
Hour00
Day of month11
Month*every value
Day of week*every value
0 0 1 * * /path/to/job

Next 10 run times

Computed when this page loaded (2026-11-11 02:24 UTC), assuming the scheduler runs in UTC.

#UTCYour local time
1Tue 2026-12-01 00:00
2Fri 2027-01-01 00:00
3Mon 2027-02-01 00:00
4Mon 2027-03-01 00:00
5Thu 2027-04-01 00:00
6Sat 2027-05-01 00:00
7Tue 2027-06-01 00:00
8Thu 2027-07-01 00:00
9Sun 2027-08-01 00:00
10Wed 2027-09-01 00:00

Things to watch with this schedule

  • A job that reports on 'last month' runs at 00:00 on the 1st, so compute the period as the previous calendar month, not the current one.
  • If the host is down at 00:00 on the 1st, classic cron does not catch up. anacron, systemd timers with Persistent=true, or Kubernetes startingDeadlineSeconds can run missed jobs.

Kubernetes CronJob

Kubernetes uses the same five fields and also accepts @monthly. Set spec.timeZone (stable since Kubernetes 1.27), otherwise the schedule follows the time zone of kube-controller-manager.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: first-day-of-every-month
spec:
  schedule: "0 0 1 * *"
  timeZone: "Etc/UTC"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 300
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: job
              image: debian:bookworm-slim
              command: ["/bin/sh", "-c", "/app/run-job.sh"]

GitHub Actions

Workflow schedules use five-field cron in UTC and run only from the default branch. Runs at minute 0 are the most likely to be delayed or dropped when GitHub is busy; an odd minute such as 7 or 23 starts more reliably. The @monthly shorthand is not accepted there.

on:
  schedule:
    - cron: '0 0 1 * *'   # UTC

jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./run-job.sh

systemd timer

The equivalent OnCalendar= value is *-*-01 00:00:00. Check it with systemd-analyze calendar '*-*-01 00:00:00', which prints the next elapse time. Persistent=true runs a missed job after downtime, which classic cron never does.

[Unit]
Description=First day of every month

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

[Install]
WantedBy=timers.target

AWS EventBridge

EventBridge rules take six fields (minute, hour, day-of-month, month, day-of-week, year) in UTC; EventBridge Scheduler can use a time zone. One of day-of-month and day-of-week must be ?, and day-of-week runs 1-7 from Sunday, so names are used here.

cron(0 0 1 * ? *)

Quartz Scheduler (Java)

Quartz adds a leading seconds field and needs ? in either day field; days of the week are 1 (SUN) to 7 (SAT).

0 0 0 1 * ?

Spring's @Scheduled(cron = ...) also uses six fields, but numbers days of the week 0-7 with Sunday as 0 or 7, like Unix cron; the names shown above work in both.

Related schedules