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
| Field | Value | Meaning |
|---|---|---|
| Minute | 0 | At minute 0 |
| Hour | 0 | At midnight (00:00) |
| Day of Month | 28-31 | Candidate 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 day0 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.