Every time I need a cron expression, I Google it. Then I tweak it wrong. Then I Google it again, find a different syntax explanation, and end up with a workflow firing at 3 AM instead of 3 PM. Built this so future me stops doing that.
How cron syntax works (the 60-second version)
Five fields, space-separated. Minute, hour, day of month, month, day of week. Each field is a number, a range, a list, an asterisk for “every,” or a slash for “every nth.”
So 0 9 * * * means “minute 0, hour 9, every day, every month, every day of week.” Daily at 9 AM. And */15 * * * * means “every 15 minutes, every hour, every day, every month, every day of week.” Run every 15 minutes.
The day-of-month and day-of-week fields are where most people trip up. If you set both to non-asterisk values, cron fires when either one matches. Set one to asterisk if you only care about the other.
Using this in n8n
Drop the expression into a Schedule Trigger node. Set the field type to “Cron Expression.” Your workflow now fires on that schedule.
One thing to watch: the schedule runs on your n8n instance’s timezone, not the user’s. If you’re sending emails to readers at 9 AM their time and your instance is on UTC, you’ll be sending them at the wrong hour for everyone outside that zone. Set the timezone in n8n’s settings before scheduling anything customer-facing.
Common patterns I keep building
Weekly digest emails fire at 0 7 * * 1, which is Monday 7 AM. Monthly reports fire at 0 8 1 * *, the first of the month at 8 AM. Quarterly check-ins fire at 0 6 1 1,4,7,10 *, the first day of January, April, July, and October at 6 AM.
The trickiest one I run is “every 30 minutes from 9 AM to 5 PM on weekdays,” which is */30 9-17 * * 1-5. Worth saving that one. Hardest to remember off the top of your head.
FAQ
Does n8n support the special @-syntax (like @daily, @hourly)?
Some cron parsers do, n8n doesn’t. Stick with the 5-field syntax above and you’ll be safe.
What if I want to fire on the last day of the month?
n8n’s cron doesn’t support the L shortcut for last day. Easiest workaround is to run on day 28-31 and add an IF node that checks whether tomorrow is the first of the next month.
Why does my workflow fire at the wrong time?
Three usual suspects. Your n8n instance is in a different timezone than you think. The expression has both day-of-month and day-of-week set (it fires when either matches). Or daylight saving time just hit and your “5 AM” became “4 AM” until the schedule resets.
Can I test a cron expression before running it?
The description below the expression in the builder tells you in plain English when it’ll fire. Read that first. If the plain English matches what you wanted, you’re good.
One thing I do every time
Before activating a scheduled workflow, I copy the cron expression into the description in plain English at the top of the workflow as a sticky note. Future me, debugging at 2 AM, doesn’t want to re-parse 15 */6 * * 1,3,5 to figure out what’s supposed to be happening.
I’m shipping more tools, templates, and blueprints over the next few weeks. Subscribe to get them, and in the meantime, automate something small today.
More tools I’ve built
If this one’s useful, the rest of the toolbelt might be too:
- Automation ROI Calculator — Run the math on whether your scheduled workflow is worth building.
- n8n Cost Calculator — Compare n8n Cloud vs self-host on Hostinger. Self-hosting saves real money once you scale past a handful of workflows.
- Webhook Tester — Most scheduled jobs end up hitting webhooks. Test what’s actually arriving.
