epochkit

Cron expression for every week

The cron expression 0 0 * * 0 runs at 12:00 AM, only on Sunday. The restricted fields are minute 0, hour 0, and day of week 0; the remaining asterisks match anything. That works out to one run per week.

0 0 * * 0

Field breakdown

Field-by-field meaning of the cron expression 0 0 * * 0
Field Value Meaning
Minute 0 The top of the hour (:00)
Hour 0 00:00 (midnight)
Day of month * Every day of the month (1–31)
Month * Every month (1–12)
Day of week 0 Sunday

Next runs

Next 5 runs Timezone: UTC

Run times are calculated in your browser timezone. The scheduler that executes the job uses its own — always UTC on Vercel Cron, UTC by default on GitHub Actions, the host clock on crontab.

How this schedule works

Cron evaluates the five fields of 0 0 * * 0 — minute, hour, day of month, month, day of week — against the clock once a minute and starts the job on any minute where all five match, which cronstrue reads as "At 12:00 AM, only on Sunday": one run per week. The day-of-week field is numbered 0 to 6 with Sunday at 0, so 0 selects Sunday. Day of month is left as an asterisk, so the calendar date is unrestricted and only the weekday decides.

When to use every week

A weekly run fits digests, rollups, rotating backups at the week boundary, and exports to an analytics warehouse where daily granularity is more than anyone needs. Sunday at 00:00 puts the run at the conventional start of the week, so the seven days it summarizes are the seven that just finished. With only 52 runs a year, each one carries weight: a single silent failure loses a week of output, which makes alerting and a documented manual re-run path far more important here than on a schedule that comes round again in five minutes.

Common mistakes with every week

A weekly schedule gets 52 chances a year to be right, which makes every mistake slow to surface and expensive when it does. The common one is the day. Cron's week starts at Sunday 0, so 0 0 * * 0 is Sunday and 0 0 * * 1 is Monday, and a report labelled weekly can be summarising a window that begins a day away from where the business thinks the week begins. The second is silence: a job that has not run for eight days is broken, but nothing in cron will say so. Alert on the absence of a successful run, not only on errors.

Platform snippets

The same expression, ready to paste into the four schedulers that read five-field cron. The notes below each snippet are the ones that follow from this schedule; the cron expression generator lists every caveat for every platform.

GitHub Actions

yaml
name: Scheduled workflow
on:
  schedule:
    - cron: '0 0 * * 0'
  workflow_dispatch:

jobs:
  scheduled:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run job
        run: echo "Running scheduled job"
  • • Workflows scheduled at the top of the hour may be delayed during high-load periods. Consider offsetting the minute field (e.g. "5 0 * * 0") for more reliable timing.

Kubernetes CronJob

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-cron-job
spec:
  schedule: "0 0 * * 0"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: job
              image: my-image:latest
              command: ["/bin/sh", "-c", "echo Running"]
          restartPolicy: OnFailure
  • • Do NOT use CRON_TZ or TZ inside the schedule string. Kubernetes 1.29+ rejects this at creation with a validation error; earlier versions issue a warning. Existing CronJobs using TZ/CRON_TZ will continue to warn on update. Use the timeZone field instead.
  • • Kubernetes supports shorthand macros: @yearly, @monthly, @weekly, @daily, @hourly.

Vercel Cron

json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "crons": [
    {
      "path": "/api/cron",
      "schedule": "0 0 * * 0"
    }
  ]
}
  • • Hobby plan: invocations occur within the specified hour (e.g. "0 8 * * *" runs between 08:00:00 and 08:59:59).

crontab

bash
# Edit your crontab: crontab -e
0 0 * * 0 /path/to/command

# With logging:
0 0 * * 0 /path/to/command >> /var/log/cron.log 2>&1
  • • Most modern implementations (vixie-cron, cronie) support shorthand macros: @yearly, @monthly, @weekly, @daily, @hourly, @reboot. These are not defined by POSIX — check your platform.

Variations

Frequently asked questions

How do I read the cron expression 0 0 * * 0?

Read the five space-separated fields left to right as minute, hour, day of month, month, and day of week. In 0 0 * * 0 the minute is 0, hour is 0, day of month is *, month is *, day of week is 0. Of the operators cron defines, this expression uses only the ones that matter here: an asterisk matches every value in its field. Put together, cronstrue reads the whole thing as "At 12:00 AM, only on Sunday", and a scheduler that checks all five fields once a minute will start the job one run per week.

What timezone does 0 0 * * 0 run in?

The expression carries no timezone of its own: it names hour 0, and the scheduler decides which hour 0 that is. Read as UTC, the run lands at 00:00 — 19:00 the previous day in New York, 00:00 in London, and 09:00 in Tokyo on a January date, with daylight saving moving the first two later in the year, so the same UTC instant is 20:00 the previous day in New York in July. That offset crosses a calendar day, and this schedule is pinned to a weekday, so the local weekday moves with it: the Sunday run at 00:00 UTC happens at 19:00 on Saturday in New York. A job that reads the weekday back from the local clock there will disagree with the expression that scheduled it. Set the zone rather than converting by hand where you can: GitHub Actions defaults to UTC but takes an optional timezone key beside cron, and a Kubernetes CronJob has spec.timeZone, stable since 1.27. Where you cannot, convert deliberately: Vercel Cron is UTC-only, and a Linux crontab follows the host clock unless CRON_TZ overrides it.

Does cron support @weekly instead of a five-field expression?

Most Linux implementations, including vixie-cron and cronie, accept the shorthand macros @yearly, @monthly, @weekly, @daily, @hourly, and @reboot, and Kubernetes CronJobs accept them too. @weekly is defined as 0 0 * * 0 — midnight on Sunday. The macros are not part of POSIX, GitHub Actions rejects them outright, and @reboot has no meaning in a hosted scheduler. Writing the five-field expression is the portable choice: it survives a move between platforms, and it states the exact day and hour instead of relying on each implementation to agree on what "weekly" means.

Related cron schedules

Build a custom schedule in the cron expression generator, or browse every epochkit tool.