This is the guide that makes n8n actually click. Almost every confusing moment in n8n - "why did this only run once," "why is my data missing," "why does this node see three things instead of one" - comes down to not yet having a mental model for how data moves. That model is simpler than it looks.
Everything is a list of items
Every node in n8n passes data to the next node as a list of items, and each item is a small JSON object. If a Google Sheets node reads 10 rows, it outputs 10 items. If an HTTP Request node calls an API that returns one object, it outputs 1 item. This is true no matter what node you're looking at - the shape is always "a list of items," even when the list has exactly one thing in it.
The rule that explains almost everything: nodes run once per item
Most action nodes run once for every item they receive. Feed a Slack node 10 items, and it sends 10 separate messages - one per item, automatically, with no loop required. This is by far the most common "aha" moment for people new to n8n: you don't write a for-loop to process a list, the node just does it for every item it's given.
Reading the data panel
Click any node after running a workflow and you'll see its output as a table or JSON, depending on the toggle in the top-right of that panel. The table view is easier to skim; the JSON view is what you'll actually reference when writing expressions in the next guide, since expressions reference the exact field names shown there.
Item linking (why "which row am I on" doesn't get lost)
n8n tracks which output item came from which input item as data flows through a workflow - this is called item linking, and it's what lets a later node reference "the same item's original email address" even after five nodes have transformed the data in between. You rarely think about this directly, but it's why expressions like $('Webhook').item.json.email (covered in the next guide) reliably point at the right record instead of a random one.
Pinning data while you build
While building a workflow, you don't want to re-trigger a real webhook or re-send a real email every time you tweak a downstream node. Click the pin icon on a node's output to "freeze" that data - later nodes will use the pinned data instead of re-running the node, which makes iterating dramatically faster and safer.