Skip to Content

What travels between nodes, and what makes a workflow start

the two ideas underneath
n8n Guide · Part 7

What travels between nodes, and what makes a workflow start

Two questions account for most of the confusion in a beginner's first week. Why did the Slack node send a hundred messages when I only asked for one? And why has my 8:00 schedule not run once all week? Both have short answers. The first is the item — the unit of data that moves from one node to the next, one row at a time. The second is the trigger — the node at the front that decides when any of it happens at all. This part settles both, and every later part comes back to them.

1 item
One record, like one row in a spreadsheet
6 fields
In n8n's Custom (Cron), not the five of Linux crontab
3 triggers
Manual, Schedule, Event — every workflow picks one
An item is a row

The single word that explains most of the surprises

If you built the “push the calendar to Slack every morning” workflow in Part 6, you probably hit a few things that did not add up.

  • The Google Calendar node runs once, reads back five events, and then the Slack node sends five messages — and nobody wrote a loop.
  • In the Expression panel {{ $json.summary }} clearly has a value, but change it to {{ $json.items[0].summary }} and you get undefined.
  • Google Sheets reads back an empty table and every node after it is skipped outright. No error is raised. It simply does not run.
  • You add one field with a Set node and the output panel shows five rows, not the single row you expected.

All four have the same cause. What travels between one n8n node and the next is not a blob of JSON. It is a list of items, one record at a time. Zapier hides this from you. n8n lays it out in front of you, which is exactly why it can do more than Zapier and why it is harder for a beginner than Zapier.

In plain terms

Every node hands the next one a spreadsheet, not a paragraph. Each row of that spreadsheet is one item. And the node receiving it does not read the sheet once — it works through it row by row, the way a mail-merge does, doing the same job again for every line it finds.

That analogy is worth taking literally, because the vocabulary maps across almost exactly.

Excel termn8n termWhat it looks like
The whole sheetThe node's output, one array[ {...}, {...}, {...} ]
One rowOne item{ name: "Elmo", age: 30 }
One columnOne field inside an itemname, age
One cellOne field's value on one item"Elmo"

Then the rule that everything else follows from: the next node runs once for every single item. Google Sheets reads back 100 rows, so the Slack node sends 100 messages. That is not a bug. It is n8n's core behavior, and the official docs call it item-based execution.

Worth a sticky note: write “item = one Excel row” and put it on your monitor. Every time a workflow behaves strangely, ask first — how many items does this node get as input? Eight times out of ten that finds the problem.

The compartments inside an item

An item is not plain JSON. It is an object with a few fixed compartments. You will only use the first of them ninety-nine percent of the time, but knowing the other two exist saves you trouble later.

CompartmentWhat goes in itWhen you need it
jsonThe main data, a plain JSON object. This is where you read 99% of the time.Almost every workflow
binaryAttached file content — PDFs, images, CSVs and other binary data.Gmail attachments, Google Drive downloads, files an API returns
pairedItemRecords which upstream item this item came from, so the Merge node can line them up.When you merge branches with the Merge node. n8n fills it in for you in most cases.

Laid out as data, one complete item has this shape:

PathValueNote
json.name"Elmo"The everyday case
json.age30Numbers stay numbers
json.emailthe contact's addressYour own data, not a value copied from here
binary.attachment.mimeType"application/pdf"Only present when a file is attached
binary.attachment.fileName"invoice.pdf"The name the file arrived with
binary.attachment.datathe file content itselfLarge, and it travels with the execution
pairedItem.item0Which upstream item this one came from

So when the next node wants the name field, the path is $json.name. Note that it is $json.name and not $json.json.name — n8n strips that outer json layer for you, to keep expressions short.

Reading an item

Four expressions, and three ways to look at the output

Switch a node field into Expression mode — the gear or the = marker at the top right of the field — and you are in expression territory. For reading item data, only four forms are worth memorizing. Everything else is a variation on them.

How to write itWhat it meansWhen to use it
{{ $json }}The whole JSON of the current item.When you want to see the whole thing, or pass the whole thing downstream
{{ $json.field }}One field of the current item.The most common one. For example {{ $json.summary }}, {{ $json.email }}
{{ $json['field with space'] }}Field names with a space, or with Chinese characters, need bracket notation.When the API returns fields named User Name or Order ID
{{ $('Google Sheets').item.json.field }}Read data from a named upstream node, not just the previous one.Reaching past the nodes in between, for data from two or three stops back

$('Node Name') means “find that upstream node's output by its name”. The node name is the one you see on the canvas — double-click a node to rename it. The advantage of writing it this way is that even with a pile of Set and IF nodes in between, you can still reach straight back for the original data.

You do not have to type any of this from memory. Click a field into Expression mode and an input panel slides out on the right. Its left half lists the data from every upstream node, in Table, JSON and Schema views, and whichever field you click, it inserts the correct expression for you. Part 10 takes that panel apart in full.

The output panel has three views, and one of them is underused

After you press Execute step on a node — running that one node on its own — or after the whole workflow finishes, the output panel on the right shows the items that node produced. Three view modes sit at the top, and each has its moment.

ViewWhat it looks likeWhen to use it
TableAn Excel-style grid. Fields are columns, items are rows.A quick look at each item's values, and a check that the item count is right. This is the default view.
JSONThe raw JSON array, with objects you can expand and collapse.When Table cannot fit it — too many fields, or a nested structure — or when you want to copy the whole thing somewhere else.
SchemaA tree of the field structure. Field names and types only, no values.Look here before you write an expression. It tells you which fields exist and how to write the path.

The top of the panel also shows the N items count. That is the number you will look at most while debugging. If it is not what you expected, something went wrong at that node, so trace upstream.

In the Table view, the small number in front of each row — 0, 1, 2 and so on — is the item index. To read a field on the first item you write $json.field, the item of the current iteration. Not $json[0].field. That is one of the most common beginner mistakes.

Schema is badly underrated. Switch to it for a moment before writing an expression and you save nine tenths of the time otherwise spent typing away only to find the field name was wrong. Clicking a field in Schema also inserts the expression into the field you are editing.
How many times it runs

Two modes, one setting, and the question everybody asks in week one

How many times a node runs is decided by two things: how many items the input has, and the node's Execute Once setting. Most built-in nodes default to “as many runs as there are input items”, but you can change that.

ModeBehaviorWhich nodes behave this way
Once for each item, the defaultN items in the input, the node runs N times, and the output is usually N items too.Most integration nodes — Slack, Gmail, HTTP Request calling an API and so on
All items in one passN items in the input, the node runs once and gets the whole array, and you decide inside how many items come out.Set, Aggregate, Item Lists, Code (switchable), Sub-workflow (switchable)

To see or change which one a node uses, click the node to open its settings, switch to the Settings tab at the top, and find the Execute Once toggle. Turn it on and the node runs once using only the first item, however many items the input has. The rest are dropped.

In plain terms

Execute Once is not a stapler. It does not gather the pile into one document. It takes the top sheet off the tray, does the job on that one, and throws the rest away. If what you wanted was the stapler, the node you are after is Aggregate.

Execute Once means “run once with the first item”, not “bundle every item together and run once”. Plenty of people mix the two up. If you really want to fold 5 items into 1, what you need is the Aggregate or Item Lists node, which Part 11 covers in detail.

Watch it happen across three nodes

Dizzy from the abstraction? Walk through the simplest possible three-node workflow once and it clicks: Manual Trigger, then Google Sheets reading rows, then Slack sending a message. Assume the sheet holds 5 rows of contacts.

NodeInput itemsWhat it doesOutput items
Manual Triggernone, it has no inputYou press Execute by hand.1 empty item, [ {} ]
Google Sheets (Read Rows)1 itemRuns once for that 1 item, and reads 5 rows back from the sheet.5 items, [{row1}, {row2}, ...]
Slack (Send Message)5 itemsOne send per item, so 5 messages go out.5 items, the result of each send
flowchart LR
  A["Manual Trigger
runs once"] -->|"1 empty item"| B["Google Sheets
Read Rows
runs once"] B -->|"5 items"| C["Slack
Send Message
runs 5 times"] C -->|"5 items"| D["Five messages sent,
no loop written anywhere"]
Where the multiplication happensThe Trigger pushes in one empty item. The middle node expands it into five. Slack is then run five times in a row, automatically, and there is not one line of loop code in the whole thing.
Look at the data source, not the Trigger. Most Trigger nodes — Manual, Schedule — emit only 1 item when they first fire. What actually multiplies the data is the reading node that comes after: Google Sheets Read, Gmail Trigger fetching new mail, a database SELECT. So when you check whether a workflow's item count is right, look at which node is the data source.

Why does my workflow run once instead of five times?

This is the question beginners ask most in their first week. The cause is always one of three, and you can pin it down by reading the item count node by node in Executions.

CauseSymptomHow to confirm
A · The Trigger emits only 1 itemSchedule Trigger and Manual Trigger send exactly 1 empty item on every fire, by default. Expecting them to run 5 times by themselves is a misreading.Read the item count in the Trigger node's output panel
B · Some node has Execute Once turned onThere are 5 items upstream but this node runs once and stops. Most likely somebody switched on Settings → Execute Once by accident.Read the output item count node by node, and find the one where 5 becomes 1
C · The expression reads the wrong levelYou think $json.items expands the items, but it only reads the field named items inside the current item — and that field is an array, not n8n's idea of items.Use the Schema view on that node's output to tell which of the two you have

Cause C is a nasty one, because “n8n items” and “a JSON field that happens to be called items” are two entirely different things. APIs very often return something shaped like this:

FieldValueWhat n8n sees
total5A field on the one item
items[ { "id": 1, "name": "A" }, { "id": 2, "name": "B" }, ... ]Still just a field. An array sitting inside a single item
The whole response1 item, because the API returned one blob

To expand that items array into 5 real n8n items, use the Split Out node, covered in Part 11, and point it at the items field. Only after that do you have 5 items, and only then does the downstream node run 5 times in a row.

flowchart TD
  A["It ran once. You expected five"] --> B{"Read the item count on
every node, left to right"} B -->|"the Trigger itself shows 1"| C["Cause A. Manual and Schedule
emit one empty item. The reading
node after them is what multiplies"] B -->|"5 goes in, 1 comes out"| D["Cause B. That node has Execute Once
switched on. Open the node,
Settings tab, turn it off"] B -->|"the count is 1 all the way"| E{"Schema view. Is it one item
holding an array?"} E -->|"yes"| F["Cause C. Add a Split Out node
and point it at that field"] E -->|"no"| G["The field name in the expression
is wrong. Read the real one
off the Schema view"]
Two questions, four endingsThe first diamond sorts on the item count you read in the output panels. The second one is not a count at all — it is the Schema view, asking whether that single item is holding an array. Three of the four endings are causes A, B and C; the fourth is a plain wrong field name, which the Schema view also tells you. Nothing here needs guesswork, and nothing needs you to change a setting before you know which one you have.

When binary data comes up

Most business workflows never touch binary at all. Only nodes that deal with a file itself produce it.

  • Gmail Trigger picks up mail with attachments, and they land in binary.attachment_0, binary.attachment_1 and so on.
  • Google Drive Download puts the file content in binary.data.
  • HTTP Request gets a PDF or image response and Response Format is set to File.
  • Read/Write Binary File, which is only meaningful when you self-host.

To look at binary, switch to the Binary tab in the output panel. It is a fourth tab alongside Table, JSON and Schema, and it only appears when there is binary to show. It lists each binary's mime type, file name and size, and images even get a preview.

Binary sits in memory and travels with the whole execution. One 10MB attachment across 100 items is 1GB. Two rules for workflows with large files: finish with it and drop it as early as you can, using a Set node to keep $json only and clear $binary; and avoid unnecessary Execute Workflow hand-offs, because a sub-workflow copies it.
Three ways to start

Something has to tell n8n when

You now know how data moves from node to node. Stop and ask the other question: when does a workflow actually start running? Only when you press the Execute Workflow button? Automatically at 8:00 every day? Or the moment a particular email arrives, or a particular URL is called?

Those three answers map onto n8n's three families of Trigger node. Every workflow has to pick one at the front — with no Trigger node, n8n has no idea when it is supposed to do the work for you. Picking the wrong one costs you directly: you wanted a daily run, you dropped in a Manual Trigger, and “why did nothing happen?” only surfaces a week later.

A Trigger node is always the leftmost, first node in a workflow. If there is no Trigger node on the canvas, the Active toggle at the top right will not switch on, and even pressing Execute Workflow raises a “Please add a Trigger node” error.

The On app event and On a schedule groups in the nodes panel hold dozens of Trigger nodes between them, but underneath they are variations on three types.

TypeWhat decides that the workflow runsTypical nodesWhen to pick it
Manual, by handYou press the button yourselfManual Trigger — When clicking “Execute workflow”While you are building or testing, and one-off jobs that should only run when a person clicks
Schedule, on a clockIt runs when the time comesSchedule TriggerFixed jobs at a fixed time, daily, hourly or weekly — reports, backups, reconciliation
Event, from outsideIt runs when something happens outsideWebhook, Gmail Trigger, Slack Trigger, Google Sheets Trigger, GitHub Trigger, RSS Feed TriggerWhen you need to react to an outside event right away — mail arrives, a form is filled in, code is pushed, a sheet is edited
flowchart TD
  A["When should this workflow run?"] --> B{"Does a person decide,
every single time?"} B -->|"yes"| C["Manual Trigger.
Building, one-off jobs,
and human approval gates"] B -->|"no"| D{"A fixed time,
or an outside event?"} D -->|"fixed time"| E["Schedule Trigger.
Daily reports, hourly syncs,
Monday morning summaries"] D -->|"outside event"| F{"Does that service
offer a webhook?"} F -->|"yes"| G["Webhook, or a push trigger
such as Slack Trigger.
Reacts in a few hundred milliseconds"] F -->|"no"| H["A poll trigger such as
Gmail Trigger. Reacts on
whatever interval you set"]
Picking the front nodeTwo questions get you to the right family. The third question, about webhooks, is the one that decides whether “immediately” is actually on the table.
Still unsure? Ask whether the thing happens at a fixed time, or is triggered from outside. Fixed time means Schedule, outside means Event. While you are building, use Manual for everything and swap it out once the tests pass.

Manual Trigger: your best friend while building

Manual Trigger is the simplest of all the triggers. It has no parameters at all — it is one node sitting there. One sentence covers how to use it: press Execute Workflow at the top right and the workflow runs once from the start.

Use itWhile building or testing. You have wired the workflow up and want the result now. Click, look, change a node, click again.
Use itFor one-off jobs — “export the full customer list for this month”. Setting up a schedule for something you run once is more trouble than it is worth.
Use itWhere a person has to make the call. “The report only goes out after the manager has checked it” turns pressing the button into an approval step.
Not thisA live workflow that has to run around the clock. Manual is a disaster here, because it never runs unless you press it.
Not thisAn outside system calling in — a LINE bot receiving a message, say. Manual cannot do this at all; you need Webhook or an Event Trigger.
A Manual Trigger does not start running by itself just because you flipped the Active toggle. The Active toggle is there for Schedule and Webhook. Manual only ever runs when you press Execute Workflow. A workflow that is already Active while its Manual Trigger sits still is normal, not broken.
Schedule and the clock

Runs on its own, if you have told it whose 8:00 you mean

Schedule Trigger is the trigger automation uses most. You set a time rule and n8n runs the workflow for you when that time comes around: push the calendar to Slack at 8:00 in the morning, sync a database once an hour, send the weekly report at 9:00 every Monday. On the canvas it stands at the far left, and when the time comes it lights up everything downstream of it.

The Trigger Interval field is where you say how often.

Trigger IntervalWhat it meansWhat you fill in
SecondsRuns every X secondsSeconds Between Triggers, for example 30 seconds
MinutesRuns every X minutesMinutes Between Triggers, for example 15 minutes
HoursRuns every X hours, and you can say which minute of the hourHours Between Triggers, Trigger at Minute
DaysRuns every X days, and you can say at which hour and minuteDays Between Triggers, Trigger at Hour, Trigger at Minute
WeeksRuns every X weeks, and you can say which days of the weekWeeks Between Triggers, Trigger on Weekdays, Trigger at Hour and Minute
MonthsRuns every X months, and you can say which day of the monthMonths Between Triggers, Trigger at Day of Month, Trigger at Hour and Minute
Custom (Cron)Write a more complex rule as a Cron expressionExpression

Two setups cover most of what people actually want:

8:00 dailyTrigger Interval Days, Days Between Triggers 1, Trigger at Hour 8, Trigger at Minute 0.
9:30 Mon–FriTrigger Interval Weeks, Weeks Between Triggers 1, tick Mon/Tue/Wed/Thu/Fri under Trigger on Weekdays, Trigger at Hour 9, Trigger at Minute 30. Or go straight to Custom (Cron) and enter 0 30 9 * * 1-5.
n8n's Custom (Cron) takes six fields, not five. The order is second minute hour day month weekday — an extra “second” at the front, unlike a traditional Linux crontab. A five-field 0 8 * * * copied from somewhere else means something different once you paste it into n8n, and may error out outright. “Every day at 8:00” is written 0 0 8 * * *.
One inconsistency worth knowing about: the source guide's own interval table gives 0 8 * * 1-5 as its Custom (Cron) example, which is five fields, while the warning a few lines later insists on six. Go with six. If your expression behaves as though every field has shifted by one position, that is what has happened.

The timezone trap

This is the one that costs people half a day. Schedule Trigger reads the clock from the workflow's timezone setting, then falls back to the instance timezone. The documented self-hosted default is America/New_York, so “8:00” may not mean 8:00 where you are. It is a common n8n scheduling mistake and it is entirely avoidable.

In plain terms

You have written “8:00” on a note and handed it to somebody in another building. They will act on it at eight o'clock by the clock on their wall. Nothing has gone wrong, and nothing will look wrong — the job just happens at a time you did not mean. The fix is to say which clock you meant, once, in writing.

There are two levels of timezone setting, and one overrides the other. Knowing which level you are editing is what saves you the half day.

LevelWhat it affectsHow to change it
Workflow level, set separately on each workflowAffects only how this workflow's Schedule Trigger reads the timeOpen the workflow → Settings at the top right, or Ctrl + , → set Timezone
Instance level, global to the whole n8n instanceEvery workflow on the instance that has no workflow-level timezone of its own falls back to thisThe environment variable GENERIC_TIMEZONE=Europe/London, and set Node.js's TZ=Europe/London to match — because if the two disagree, values such as new Date() can differ from the schedule clock
Europe/London here is only an example. Replace it with the IANA timezone for your own location wherever it appears. And the instance-level change means changing server settings — if that is not your job, ask whoever runs the server.

The precedence is: workflow level, then instance level, then the documented America/New_York default. Which gives you three things to do, in this order.

  1. Step 1

    Check the instance timezone instead of assuming it

    Ask the administrator whether GENERIC_TIMEZONE is set to an appropriate value. Or find out for yourself: build a test workflow, run it every minute, and check whether the times on the Executions page match the intended local time. If they do, the instance default is suitable — though an explicit workflow timezone is still safer when portability matters.

  2. Step 2

    If they are wrong, set the workflow level

    Open the workflow's three-dot menu at the top right → Settings. There is a Timezone dropdown in the middle. Pick your IANA timezone and save when you are done.

  3. Step 3

    Check every workflow that has a Schedule Trigger

    Workflow-level settings are independent of each other. Even with workflow A set, a new workflow B has to be set again if the instance level is something else.

Read it off the node. Not sure which timezone a workflow is on right now? Open the Schedule Trigger node and n8n usually shows a value along the lines of “Next execution at” followed by a date, a time and a timezone in parentheses. Whatever is in the parentheses is the timezone it is using, visible at a glance.
Events, push and poll

When the outside world does the acting

Event triggers are the family that feels most like magic, because you are not the one acting — the outside world is. Someone fills in a form, mail arrives, a sheet is edited, someone pushes to GitHub, and n8n runs on its own. These are the ones you will meet most.

NodeWhat sets it offTypical use
WebhookAn HTTP call hits the URL you handed outA LINE bot receiving a message, a Typeform submission, a Home Assistant automation calling in, a third-party system posting back a callback
Gmail TriggerNew mail arrives in Gmail, and you can filter by label or senderPull the data out of a customer email and open a ticket the moment it lands; file invoice emails into Drive automatically
Slack TriggerA new message, an @-mention of you, a new channel, an emoji reaction@ the bot and it looks something up; auto-reply whenever a keyword shows up
Google Sheets TriggerA row is added to a sheet, or a row changesSend a welcome email as soon as someone signs up on the form; tell sales when the quote sheet changes
Airtable TriggerA new or changed Airtable recordOpen a Slack channel when the CRM gets a new customer; send a closing email when a task turns Done
GitHub Triggerpush, PR opened, issue created, releaseDeploy automatically when a PR is merged; tell the team when an issue is filed
RSS Feed TriggerA new item in an RSS feedPost to Slack when the blog publishes something; email a digest when a news site updates
Chat TriggerSomeone types a message into n8n's chat interfaceBuilding an internal chatbot or AI Agent assistant, which Part 16 onwards uses

Webhook is the king of the family, because it takes anything that can call in over HTTP. Part 17 is entirely about it; for now it is enough to know it exists.

An Event Trigger only listens once the workflow is Active. Flip the Active toggle at the top right to green. An Event Trigger that is not Active is ready but off duty — even with Gmail Trigger set up correctly, n8n ignores new mail entirely while Active is OFF.

Why Gmail is always a beat behind

Underneath, event triggers split into two mechanisms, and that split is what decides how fast they react.

MechanismHow it worksResponse speedWhich nodes work this way
Push, the Webhook kindWhen something happens on the other system, it calls your URL over HTTPImmediate, a few hundred millisecondsWebhook, GitHub Trigger, Slack Trigger — parts of it go through the events API
Poll, the polling kindn8n asks the other API on a timer whether there is anything newDepends on the interval you set, usually 1 minute to 1 hourGmail Trigger, Google Sheets Trigger, Airtable Trigger, RSS Feed Trigger
In plain terms

Push is a doorbell. Poll is walking down to the letterbox every five minutes to see whether anything has come. Both get you the post. Only one of them gets it the moment it lands, and with the second one the wait is however long you set between trips.

sequenceDiagram
  participant O as Outside service
  participant N as n8n
  Note over O,N: Push, the Webhook kind
  O->>N: Something happened, calling your URL
  N->>N: Workflow starts a few hundred milliseconds later
  Note over O,N: Poll, the Gmail Trigger kind
  N->>O: Anything new since I last asked?
  O-->>N: Nothing
  Note over O,N: the mail actually arrives about here
  N->>O: Anything new since I last asked?
  O-->>N: Yes, one message
  N->>N: Workflow starts, up to one poll interval late
Two mechanisms, drawn on the same clockIn the poll case nothing is broken. The gap between the mail arriving and the workflow starting is the interval you chose, and it is the price of a service that has no webhook.

So Gmail Trigger does not run the moment mail arrives. Every X minutes, n8n asks the Gmail API whether anything new has come in since it last asked. With a poll interval of 5 minutes, new mail waits up to 5 minutes before the workflow starts. To go faster, drop the poll interval to 1 minute — the shortest the Community edition allows — but you make more API calls and may run into the other side's rate limit.

Need millisecond-level reaction? Look for an option that has a webhook. For “run when a new Slack message arrives”, Slack Trigger, which goes through Slack's events API as a push, is far faster than a Gmail-Trigger-style poll. When you design a workflow, ask first: does this service have a webhook?

One workflow can have several triggers

n8n lets you put several Trigger nodes on one workflow. They sit side by side, not in series — whichever one fires, the same downstream workflow runs. Three patterns are worth knowing.

Schedule and Manual

The most common one. The daily report goes out automatically at 8:00, but you suddenly want to send it again right now. Add a Manual Trigger beside the Schedule Trigger and pressing Execute Workflow runs it immediately.

Webhook and Schedule

A safety net. Normally the webhook reacts in real time, but in case a webhook is ever missed, a Schedule sweeps the database once an hour for anything left unprocessed and runs it again.

Several event triggers converging

A message from Gmail or from Slack should open the same kind of ticket. Put a Gmail Trigger and a Slack Trigger side by side, share one set of downstream logic, and data from both sides takes the same path.

flowchart LR
  A["Schedule Trigger
08:00 every day"] --> C["Downstream node A"] B["Manual Trigger
when you press the button"] --> C C --> D["Downstream node B"]
Two triggers, one workflowSide by side, not in series. Either entry point leads into the same downstream nodes, and only the one that fired supplies the data for that run.
Parallel triggers hand downstream nodes different shapes of data. A Gmail item and a Slack item have completely different JSON structures. Normalize the fields first — with an expression from Part 10, or the Set node from Part 13 — so the downstream nodes have something consistent to work with.
Manual to Schedule

Hands-on: retiring the test trigger

Say the workflow you built in Part 6 starts with a Manual Trigger because you were testing. That was the right choice at the time. Now the testing is over and you want it to run by itself at 9:30 every morning.

  1. Step 1

    Open that workflow

    Go in through the Workflows list on the left. Right now it starts with a Manual Trigger node, with your existing downstream nodes to its right.

  2. Step 2

    Delete the Manual Trigger node

    Right-click the Manual Trigger node → Delete, or select it and press Delete or Backspace. The connection to the downstream nodes breaks and the first downstream node is left floating on the canvas. Do not panic; that is expected.

  3. Step 3

    Add a Schedule Trigger

    Click + at the top left of the canvas, or press Tab on an empty spot, to open the nodes panel. Pick On a schedule → Schedule Trigger. It drops onto the canvas.

  4. Step 4

    Set the time

    Open the node panel and set Trigger Interval to Days, Days Between Triggers 1, Trigger at Hour 9, Trigger at Minute 30. Look at the Next execution shown under the node and check that the timezone in parentheses is the one you intended. If it is not, set it as described in the previous section.

  5. Step 5

    Connect it to your existing nodes

    Drag from the connector dot on the right of the Schedule Trigger to the dot on the left of the first downstream node. A successful connection shows as a solid line.

  6. Step 6

    Save, then switch on Active

    Press Ctrl + S to save, then drag the Active toggle at the top right to green. This is the step everyone forgets. A Schedule with Active OFF never runs by itself, and finding that out tomorrow morning does not help you.

  7. Step 7

    Verify with one manual run

    Once it is Active you can still press Execute Workflow for a manual run, which tests whether the Schedule Trigger path makes it all the way through. If that run succeeds, tomorrow at 9:30 it will fire on its own.

  8. Step 8

    Check Executions the next day

    In Executions on the left, or the Executions tab inside that workflow, you will see the record of the automatic run at 9:30 the next day. A record means the schedule is alive. No record means go to the next section.

When it misbehaves

The faults you will actually hit, and what each one means

Two lists here, because the two halves of this part fail in different ways. First the item faults, then the trigger faults.

Items behaving oddly

  • An expression shows undefined. Two possibilities. The field name is wrong — switch to the Schema view and read the real one, checking case, spaces and whether there is a data. prefix. Or the upstream node never ran successfully, in which case its output panel is empty or red. Fix the upstream node first, then worry about the expression.
  • A node runs 100 times when you only wanted 1. That is because there are 100 items upstream. Three approaches: drop an Aggregate node in between to fold the 100 into 1; use a Code node, covered in Part 15, with return [ { json: { all: $input.all() } } ]; or, if you only want the first record, turn on Execute Once in that node's Settings — remembering that this means “take the first one”, not “combine them all”.
  • The Merge node's item count does not add up. Merge has four modes and the wrong one changes the result completely. Append puts them end to end, so A's 3 plus B's 2 is 5. Combine then splits into three sub-options: Matching Fields compares field values like a SQL join, Position pairs up the same index, and All Possible Combinations is a Cartesian product, so A's 3 by B's 2 is 6. SQL Query (1.49.0 and later) lets you write the SQL yourself. Choose Branch emits the data from one side only. Older docs call All Possible Combinations Multiplex; the newer name replaced it, so do not panic when someone else's workflow still uses the old one. Part 11 goes into more detail.
  • A node gets 0 items and is skipped. That is how n8n behaves: when the input is an empty array, the node does not run. It is deliberate, so you never have to write an empty check, but beginners read it as a broken node. Trace upstream to find who emitted 0 — usually neither IF branch passed, Google Sheets Read found no data, or a filter node filtered everything out.
  • The item count is wrong after a Set node. The Set node runs once for each item by default, so the item count stays the same, and that is correct. If you see 5 in and 5 out but the fields have gone missing, the Set node's mode is usually on Keep Only Set, which wipes out the original fields. Try Include All Fields or Include Selected Fields instead. Part 13 takes the Set node apart in full.
  • The expression preview does not match what actually runs. The expression editor previews against the upstream node's output from its last run. If the upstream node has not run yet, or ran wrong, the preview shows a stale value. Press Execute step on the upstream node to make it produce fresh output, then come back and look again.

Triggers not firing

SymptomLikely causeHow to fix it
The Schedule time came and went with no runThe Active toggle at the top right is OFFOpen the workflow and drag Active to green. This is the number-one gotcha.
The Schedule runs at the wrong local timeNo workflow Timezone is set, so it falls back to the instance settingWorkflow → Settings → choose your IANA timezone, save, then inspect the next execution time
The Webhook Trigger URL was called but nothing ranWhat you have is the Test URL. A Test URL is only alive while you have pressed “Listen for test event”, or for the moment right after a single run while the workflow is not Active, and it dies when you close the canvasUse the Production URL — you switch between them in the Webhook node panel — and make sure the workflow is Active. Part 17 has the details.
Gmail clearly received the mail but the trigger did not fireThe poll interval is long and has not come round yet; or a filter on the Gmail side archived the mail or sent it to spam; or the OAuth scope you authorized does not cover that labelSet Poll Times to Every Minute first to rule out the interval, then check the filters on the Gmail side, and finally reconnect the OAuth credential
The time is right and Active is on, but it still does not runYou navigated away without saving; or the Trigger node was right-click Disabled, so it looks gray; or the workflow was copied from another one and the trigger was never set up againSave once; right-click the Trigger node to see whether it is Disabled and pick Enable; reopen the Trigger node and save again so the settings are written
Pressing Execute Workflow on a Manual Trigger does nothingThere are several Trigger nodes on the canvas and the Manual Trigger is not connected to anything downstreamCheck the connection. The dot on the right of the Manual Trigger has to reach the dot on the left of the downstream node.
A Schedule running every minute is too often and you want to stop itYou forgot that the workflow's Active is ONJust switch the Active toggle off. There is no need to delete the Trigger node.

Questions people ask

Does Zapier have this item idea too?
It does, but Zapier hides it. By default every Zap fires on one record, and handling several means adding a Sub-Zap or Looping by Zapier. n8n chose to lay items out in front of you. The upside is flexibility — the same workflow handles 1 record or 1000. The price is the extra thirty minutes a beginner spends on this idea. Once it clicks, you will find Zapier's black box gets in your way instead.
How many items can it take at once? Is there a ceiling?
There is no hard limit technically, but there is one in practice: n8n keeps a whole execution's items in memory. A few thousand plain-JSON records are fine, tens of thousands get slow, and one or two hundred carrying binary can blow it up. For genuinely large volumes, batch the work with the Split In Batches node (Part 11), or do the data processing in the database layer and let n8n touch only the result.
Does binary data take up memory?
It does, and it is greedy. A 10MB PDF attachment sits whole in the execution's memory, and if it then triggers a sub-workflow it gets copied as well. Three rules: use a Set node to clear binary from items that do not need it; remember that the Cloud edition has an execution size limit and going over it fails; and when you self-host, watch the n8n container's memory usage.
What is the difference between $json and $input.all()?
In an Expression field on an ordinary node, $json is the json of the item in the current iteration — because the node runs N times in a row, each pass points $json at a different item. $input.all() gives you the array of all the items this one node received; it returns an Array whose members are complete items, with .json and .binary. Expressions can call it too, but in practice you use it most in the Code node (Part 15), because a Code node is usually set to handle everything in one pass. Its siblings are $input.first(), $input.last() and $input.item.
How do I see how long the workflow ran, and how long each node took?
Every record on the Executions page in the sidebar carries a total duration. Open one and you can see how long each node took on its own, from the small clock marker at the node's top right. The slow nodes are usually the ones calling outside APIs — Slack, the Google family, HTTP Request — not n8n itself. Part 12 on error handling covers how to set timeouts and retries.
Can I run the workflow on only some of the items instead of all of them?
You can. Put an IF or Filter node in between to filter on a condition: only the items that match carry on, the rest are stopped. Or use Split In Batches to work through them in batches, say 10 at a time for 10 rounds. Part 11 covers all of this in detail.
What is the shortest interval a Schedule Trigger can run at?
In theory the Community edition lets you go down to once every 1 second, with Seconds Between Triggers set to 1, but in practice that pins the CPU and the Executions history explodes. A sane range is one minute or longer. If you need it faster than that, do not use Schedule — go to Webhook instead. n8n Cloud has a minimum interval that varies by plan, 1 minute on some plans, so check your own subscription terms.
Can I set the timezone for every workflow at once?
Yes, but it means changing the server environment variable, for example GENERIC_TIMEZONE=Europe/London. That is an instance-level setting, so only an admin or someone with IT access can change it. Do not assume the instance matches your location; ask the administrator, or build a one-minute test workflow and inspect its execution times. The guide's settings appendix and the n8n timezone documentation carry the full list of environment variables.
Can one Trigger node serve several workflows at the same time?
No. A Trigger node belongs only to the workflow it sits in. If two workflows both want to run at 8:00 in the morning, each one gets its own Schedule Trigger. To avoid the duplication, pull the shared logic out into a sub-workflow, covered in Part 14 — each trigger then calls the same sub-workflow, which gives you one piece of logic with several entry points.
Does a Webhook Trigger's URL change every time?
No. The Production URL is fixed — once the workflow is Active, the URL is bound to that workflow and stays put. Watch out for one thing though: the Test URL is only alive while you are on the canvas listening, and it dies when you close the canvas or navigate away. Use the Test URL to look at data while you build, and hand the Production URL to the other system when you go live. Part 17 covers this in detail.
Does firing a trigger use up execution quota?
On n8n Cloud, every workflow run a trigger sets off counts as one execution against your monthly quota — 5,000, 10,000, or more, depending on the plan. On Community or self-hosted — Woow n8n is one of these — there is no limit on the number of runs. Schedule it every minute if you want, as long as the server can take it. How many days of Executions history to keep is configurable.
Is Schedule Trigger the same as the cron in a scheduling system?
The syntax is close, but the number of fields differs. A traditional Linux crontab has five fields — minute hour day month weekday. The Custom (Cron) in n8n's Schedule Trigger has six: second minute hour day month weekday. Common examples, remembering the seconds field: 0 0 8 * * * is 8:00 every day, 0 0 8 * * 1-5 is 8:00 Monday to Friday, 0 */15 * * * * is every 15 minutes, and 0 0 9 1 * * is 9:00 on the 1st of every month. When you copy a five-field expression from a crontab reference site, remember to add a 0 at the front, or the meaning shifts completely or it errors out.
If my workflow errors and does not finish, will it still run at the next Schedule?
Yes. Schedule Trigger does not care about the previous result — when the time comes it starts another new execution. The data from the failed run is not retried automatically. For automatic error handling — retries, notifications, a fallback — you set up an Error workflow or node-level Retry on fail separately. That is what Part 12 is about.
My Manual Trigger says “Test workflow”, not “Execute workflow”. Is that a different thing?
No. Older n8n versions called the button “Execute Workflow”; newer ones renamed it “Test workflow”, and some carry both. They mean the same action: you press it and the workflow runs once, starting from the Manual Trigger. The name changed, the function did not. Whatever your build puts on that top-right button is what it is called for you.
Next

Where to go from here

keep going

You can read the data and you can start the clock.

That is the whole of the foundation. Part 8 leaves the theory behind and starts connecting real services — the SaaS integrations most people set up first, and what each one actually needs from you before it will work.

Open the full guide

Part 7 of the Woow n8n Onboarding Guide series on the Apporo blog.

Adapted from the Woow n8n Onboarding Guide, produced by WoowTech and released under CC BY 4.0. This adaptation is published by Apporo under the same licence.

Light · Air · Water · Control · apporo

in n8n
Your first workflow: today's calendar in Slack, every morning at eight