N8n tutorials

Schedule Triggers vs Webhooks: Choosing the Right Trigger for the Job

Almost every workflow we build starts from one of two nodes: a Schedule Trigger or a Webhook. They sound like they’re solving the same problem, getting a workflow to start, but they work in opposite directions, and picking the wrong one for a given job usually shows up later as a workflow that runs when nothing actually happened, or one that silently never runs at all.

Two different ideas of “start”

A Schedule Trigger is n8n watching its own clock. Nothing outside the workflow tells it anything; it just wakes up on whatever interval you’ve configured and runs, whether or not there’s anything new to do.

A Webhook is the opposite. The workflow sits completely idle until some external system sends an HTTP request to the URL n8n hands it. n8n isn’t checking anything on its own. It’s waiting to be told.

That difference in direction is really the whole decision. If the thing you’re automating happens on a clock, regardless of external events, that’s a schedule. If it happens because something else just occurred somewhere else, that’s a webhook.

How the Schedule Trigger actually works

The node’s configuration is a list of “Trigger Rules,” and you can add more than one, which is useful when a workflow needs to run at two unrelated times, say every weekday morning and again on Friday evening, without needing a second workflow.

Each rule picks an interval type: seconds, minutes, hours, days, weeks, months, or a custom cron expression. The day/week/month options let you set a specific hour and minute to trigger at, so “every day at 9am” doesn’t require touching cron syntax at all. Cron is there for anything more specific, using the standard six-field format n8n exposes right in the node (seconds, minutes, hours, day of month, month, day of week), and the UI links out to crontab.guru if you want help building one.

The gotcha worth knowing before you hit it: the hour you set is evaluated against a timezone, and that timezone comes from the workflow’s own settings first, falling back to the instance default if the workflow doesn’t specify one. On a self-hosted instance that default is America/New York unless someone’s changed it, so a schedule that fires three hours off from what you expected is almost always a timezone setting, not a broken cron expression. It’s the first thing worth checking, before you start doubting the interval math.

One more edge case: if you set a monthly trigger for day 30 or 31, any month that doesn’t have that day just doesn’t fire. n8n won’t roll it forward to the 1st or back to the last day of the month for you.

How the Webhook actually works

A Webhook node gives you a path, and that path resolves to two different URLs. The test URL goes live as soon as you click “Listen for Test Event” or manually execute the workflow, and requests sent to it show up directly in the editor so you can inspect the payload while you build. The production URL only goes live once the workflow is activated, and once it is, incoming data stops appearing inline in the canvas. You check the Executions tab instead. This trips people up the first time: they build and test against the test URL, get comfortable seeing data flow through the canvas, then activate the workflow and assume it’s broken because nothing shows up in the editor anymore. It isn’t broken. That’s just what “production” means for this node.

Authentication is worth deciding deliberately rather than leaving on the default. “None” is fine while you’re still building something internal, but anything that touches real data should have at least Header Auth in front of it, since an unauthenticated webhook URL is effectively public the moment someone finds or guesses it. There’s also an IP allowlist option if you know exactly which system will be calling in, and an “Only Run If” expression that lets a single webhook path filter out requests it doesn’t care about (useful when one endpoint handles several event types from the same provider) without spinning up a full execution for every request that doesn’t match.

Payload size is capped at 16MB by default, which is a self-hosted-only setting you can raise via an environment variable if you’re ever pushing large files through one.

Deciding which one you actually need

The test we use is simple: if you’d have to keep checking to know something happened, it’s an event, and events belong behind a webhook. If you’d check on it once a day regardless of whether anything changed, it’s a schedule.

A form submission, an incoming payment, a message posted in a channel, a deploy finishing somewhere: these are all things with a system on the other end that can tell you the instant they happen, so a webhook is the right shape. A nightly report, a weekly cleanup job, a daily sync between two systems that don’t talk to each other directly: none of those are waiting on an event, so a schedule is the right shape, even if the underlying data changes throughout the day.

Some workflows legitimately want both. A webhook reacts to signups in real time, and a nightly schedule runs a reconciliation pass that catches anything the webhook missed, whether from downtime, a dropped request, or the sending system just failing to call you. That’s not redundant engineering, it’s insurance for the cases where a missed webhook call actually costs something.

Where this series goes next

Both of these triggers hand data to the rest of your workflow the moment they fire, but that data rarely arrives in the shape you actually need it in. Next we’ll get into the Set, Function, and Code nodes and how to reshape, clean up, and transform that data once it’s inside your workflow.

Need this automated for you?

Like this workflow? We build these for teams every week.

DepChip designs and ships practical automation and AI-integrated systems — from a single n8n workflow to a full internal platform. If this post solved a problem you recognize, we can help you take it further.