Cron Last Day of Month

Standard cron cannot express "last day of month" directly because months vary in length. The reliable pattern runs on days 28-31 and adds a guard in the command that only proceeds if tomorrow is the 1st. Some implementations (e.g. some Quartz/systemd setups) support an L token, but vixie-cron does not.

Cron Expression
0 0 28-31 * *

Field Breakdown

FieldValueMeaning
Minute0At minute 0
Hour0At midnight (00:00)
Day of Month28-31Candidate last days — gate the command with a tomorrow check
Month*Every month (1-12)
Day of Week*Any day of the week

Variations

0 0 28-31 * * [ "$(date +\%d -d tomorrow)" = "01" ] && /path/to/jobRuns only when tomorrow is the 1st — i.e. the true last day
0 0 L * *Last-day token — works only where the cron implementation supports L (not vixie-cron)

Common Use Cases

  • Month-end financial close and reconciliation
  • End-of-month reports and statements
  • Final monthly backups before counters reset

Tips & Best Practices

In crontab, percent signs must be escaped, so date +\%d is required inside the command.

Do not rely on 0 0 31 * * — months without a 31st would skip entirely.

If your scheduler supports it, systemd timers express "last day" far more cleanly than cron.

Related Intervals