Tutorial

Run on the first of the month.

Use 0 0 1 * * — at midnight on day 1 of every month. Or the macro @monthly, which is identical.

The expression

@monthly /path/to/script.sh
# Equivalent to:
0 0 1 * * /path/to/script.sh

Variations

ExpressionWhen
0 0 1 * *1st of every month, midnight
0 9 1 * *1st of every month, 9 AM
0 0 15 * *15th of every month, midnight
0 0 1 1,4,7,10 *1st of Jan, Apr, Jul, Oct (quarterly)
0 0 1 */3 *Quarterly (same as above, step syntax)

Last day of the month — harder than you'd think

Standard Unix cron has no built-in way to express "last day of the month" because months have different lengths. Workarounds:

Quartz / AWS — use L

# Quartz
0 0 0 L * ?

# AWS EventBridge
cron(0 0 L * ? *)

Unix cron — gate inside the script

# Run on 28-31, but check inside the script
0 0 28-31 * * [ $(date -d tomorrow +\%d) = 01 ] && /path/to/script.sh

The check date -d tomorrow +%d = 01 only returns true when tomorrow is the 1st — i.e., today is the last day of the month.

First weekday of the month

To run on the first weekday — skipping if the 1st is a Saturday or Sunday:

# In Quartz, use the W modifier
0 0 0 1W * ?

# In Unix cron, gate inside the script
0 0 1-3 * * [ $(date +\%u) -le 5 ] && /path/to/script.sh

The Unix version fires on the 1st, 2nd, OR 3rd, but only if it's a weekday — so the first weekday of the month gets caught.

Platform examples

Linux crontab

0 0 1 * * /usr/local/bin/monthly-report.sh

AWS EventBridge

cron(0 0 1 * ? *)

Kubernetes CronJob

schedule: "0 0 1 * *"

For more on the L/W operators, see What does "L" mean in cron?.

Related

Continue reading.