UtilToolkits2025-12-22
TL;DR — The Cron Expression Generator builds cron strings visually, translates them to plain English, and shows the next 5 fire times so you can verify before deploying. For related work see the Unix Timestamp Converter and Date Calculator.
Cron has no "are you sure?". You ship */5 * * * * thinking "every 5 hours" when it actually means "every 5 minutes" — and now your nightly DB dump runs 288 times a day and your bill spikes. One asterisk in the wrong field becomes a 3 AM page.
┌─────── minute (0-59)
│ ┌───── hour (0-23)
│ │ ┌─── day of month (1-31)
│ │ │ ┌─ month (1-12)
│ │ │ │ ┌ day of week (0-6, Sun-Sat)
│ │ │ │ │
* * * * *
| Expression | Means |
|---|---|
0 0 * * * | Every day at midnight (server time) |
*/15 * * * * | Every 15 minutes |
0 9 * * 1-5 | 9:00 AM on weekdays |
0 0 1 * * | Midnight on the 1st of every month |
0 */6 * * * | Every 6 hours (00, 06, 12, 18) |
30 2 * * 0 | 2:30 AM every Sunday |
For event-driven triggers (file uploaded, message in queue), use a real job runner. Cron is best for periodic, idempotent maintenance: backups, cleanup, report generation, cache warmup. If your job must run exactly once or has complex dependencies, reach for a workflow engine (Airflow, Temporal, GitHub Actions with conditions).
The server’s local time by default. Set CRON_TZ=UTC at the top of crontab or use platform-specific TZ config to make it explicit.
0 0 31 2 * job ever run?February doesn’t have a 31st. Cron silently skips impossible dates. Use the generator’s "next runs" preview to catch this.
You can’t in standard cron — only divisors of 60 work cleanly with */n. Use two entries (0 0,3,6,9,12,15,18,21 * * *) or move to a job runner.
One minute. For anything more frequent, use a long-running worker or an event-driven trigger.