Lesson 1: What Is n8n? (Nodes, Triggers & Workflows Explained)
š Full written solution: https://interview-kit-fe.vercel.app/n8n-lesson-01-what-is-n8n-and-workflow-automation š» Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/n8n-lesson-01-what-is-n8n-and-workflow-automation Chapters: 0:00 Five Apps Before Coffee 0:12 The Real Question 0:23 What n8n Is 0:36 The Smallest Piece: a Node 0:49 Chain Nodes: a Workflow 1:00 What Kicks It Off: a Trigger 1:11 Proof It Ran: an Execution 1:24 Watch the Data Move 1:36 n8n vs Zapier vs Make 1:49 Where It Actually Runs 2:07 My Honest Take 2:22 A Mistake I Made Early On 2:35 The Four Building Blocks Start here: Lesson 1 breaks down n8n from zero ā what a node is, how nodes chain into a workflow, what a trigger actually kicks off, and how an execution proves your automation ran. We also compare n8n against Zapier and Make, look at where n8n runs (cloud vs self-hosted), and I share a mistake I made early on with triggers so you don't repeat it. #n8n #workflowautomation #nocode #automation #n8ntutorial Watch next: - One Access Pattern Makes This 1000x Slower #shorts: https://youtu.be/ti3W06bT4MU - This Video Took 4 Seconds To Make #shorts: https://youtu.be/WRPkaqqoeGc - Lesson 16: What Does __name__ == '__main__' Actually Do?: https://youtu.be/2WXujnjr5cI
Introduction
Every developer has lived some version of the same morning: a lead lands in your inbox, and you copy a name into a spreadsheet, then retype the same three facts into a Slack message. Nothing about that work requires a human brain ā it requires hands, and hands are the most expensive part of the process.
This is the exact problem n8n exists to solve, and it's worth understanding well because workflow automation has quietly become a core skill for developers. Companies don't just want engineers who can write code from scratch anymore ā they want engineers who know how to connect systems that already exist, cut out manual busywork, and build reliable pipelines between tools that were never designed to talk to each other. If you've touched backend integrations, internal tooling, or DevOps, you've already brushed up against the ideas n8n is built on: events, triggers, data transformation, and execution logging.
This lesson is the foundation. Before you can build anything real in n8n, you need four concepts locked in: what a node is, how nodes become a workflow, what starts a workflow, and how you prove it actually ran. Get these four right and everything else in n8n ā HTTP requests, conditionals, loops, error handling ā is just variations on the same pattern.
Problem Overview
Picture a small business process: a new lead arrives by email, someone logs it in a spreadsheet for record-keeping, and someone else posts a summary in a team Slack channel so the sales team notices immediately.
Three tools ā Gmail, Google Sheets, and Slack ā each hold a piece of the picture, but none of them are aware the other two exist. Gmail doesn't know Sheets exists. Sheets doesn't know Slack exists. The only thing stitching them together is a person, doing the same three-step manual transfer every single time a lead comes in.
That manual stitching is the actual problem. It's not that the data is hard to get ā it's that a human has become the integration layer between systems that should be talking directly to each other. n8n's job is to replace that human wiring with an automated, repeatable, observable process.
Example
Let's make this concrete with the exact scenario from the lesson:
- A new lead email lands in Gmail.
- The name and contact info get copied into a Google Sheet as a permanent record.
- A short summary gets posted into a Slack channel so the sales team can act on it.
Manually, that's three separate actions, three separate app windows, and one person acting as the messenger between them. Automated with n8n, it becomes a single workflow: new lead detected ā row added to sheet ā message posted to Slack. The trigger, the middle step, and the final action are stitched together once, and after that, they run themselves every time a new lead shows up ā no matter if it happens once a week or fifty times a day.
Intuition
Here's how an experienced engineer actually arrives at this solution, rather than just being told the answer.
Start by asking: what is actually changing hands here? Not tools, not UI ā data. A name and an email address are being copied from one system's storage into two other systems' storage. That's it. Once you see it as data movement rather than "using an app," the solution becomes obvious: you don't need three humans clicking around three interfaces, you need one pipe that carries the data from the first system to the other two.
The next question an experienced engineer asks is: how do I break this pipe into pieces I can reason about independently? You don't want one giant tangled script that does everything at once, because when it breaks, you won't know which part failed. So you decompose the pipe into discrete steps ā one step per action. That decomposition is exactly what a "node" is in n8n: one action, isolated, testable, and swappable.
Once you have discrete steps, order matters. "Add row" has to happen with the lead's data already available, so it must come after the lead arrives, and "notify Slack" is the last thing that should happen, since it's the human-facing summary of everything that already occurred. Chaining these ordered steps together is a workflow.
But a workflow sitting idle does nothing ā something external has to kick it off. That's the role of a trigger: it's the event that says "start now," whether that's a new email arriving, a scheduled time of day, or a webhook ping from another system.
Finally, once something runs automatically and unattended, you lose the ability to just watch it happen. You need a record of what happened and when ā which is why every run generates an execution log. Without it, debugging an automation that fails at 2 a.m. would be guesswork.
Nodes, workflows, triggers, and executions aren't four unrelated features ā they're the natural decomposition of "replace a human doing repetitive multi-app work" into something a machine can run reliably and you can debug when it doesn't.
Brute Force Solution
The "brute force" version of this problem is simply not automating it ā a human repeats the copy-paste-type sequence manually every time a lead comes in.
Idea: A person monitors Gmail, and on seeing a new lead, manually transcribes the relevant fields into Sheets and Slack.
Algorithm:
- Watch inbox for new leads.
- On arrival, extract name and contact details.
- Open Sheets, paste into a new row.
- Open Slack, type a summary message, send.
Advantages:
- Zero setup cost ā no tooling, no learning curve.
- Full manual judgment on edge cases (e.g., deciding a lead looks like spam).
Disadvantages:
- Doesn't scale ā every additional lead costs the same amount of human time.
- Error-prone ā manual retyping introduces typos and dropped fields.
- No log ā if a lead gets missed, there's no record showing where the process broke.
- Bottlenecked by availability ā nothing happens if the person is offline or asleep.
Time complexity: O(n) human-minutes per n leads, with a high constant factor. Space complexity: O(1) additional storage beyond what Gmail, Sheets, and Slack already hold ā but effectively unbounded "space" in the sense of someone's attention and time.
Optimal Solution
The optimal solution is the n8n workflow itself, and it's optimal because it replaces linear human effort with a fixed one-time setup cost.
Here's the shape of it:
| Stage | Role | Example |
|---|---|---|
| Trigger | Starts the workflow | New email received in Gmail |
| Node 1 | First action | Extract lead name/email from message |
| Node 2 | Second action | Add a row to Google Sheets |
| Node 3 | Third action | Post a summary message to Slack |
| Execution | Proof of run | Log entry showing exact data that flowed through |
The key mental model, straight from the lesson: watch the data move left to right. It enters at the trigger, gets read and possibly reshaped at each node, and lands at the final action. Nothing here is "magic" ā it's a value getting passed and transformed one step at a time, the same way data flows through a pipeline of functions in code.
Two design decisions matter for building this well:
One workflow, one job. A workflow trying to do five unrelated things at once becomes impossible to debug ā when it breaks, you won't know which of the five jobs caused it. Keep each workflow scoped to a single clear purpose, the same discipline you'd apply to writing a single-responsibility function.
Pick your trigger deliberately. A trigger can be a schedule (run at 9 a.m. daily), a webhook (another app pings n8n when something happens), or a manual click. The trigger type shapes the whole workflow's behavior ā a scheduled trigger checks for changes periodically, while a webhook trigger reacts instantly.
Python Code
n8n itself is a visual, node-based tool ā you're not writing Python inside it for basic workflows. But it's useful to see the equivalent logic in Python, since it reveals that a workflow is fundamentally a small, ordered function pipeline with a triggering condition:
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class Execution:
"""Represents one workflow run and what data flowed through it."""
workflow_name: str
started_at: datetime = field(default_factory=datetime.now)
steps: list = field(default_factory=list)
status: str = "running"
def log_step(self, node_name: str, data: dict) -> None:
self.steps.append({"node": node_name, "data": dict(data)})
def finish(self, status: str = "success") -> None:
self.status = status
def extract_lead(data: dict) -> dict:
"""Node 1: pull the fields we care about from the raw event."""
return {"name": data["name"], "email": data["email"]}
def add_row_to_sheet(data: dict) -> dict:
"""Node 2: simulate writing a row to a spreadsheet."""
print(f"Sheet row added: {data['name']} <{data['email']}>")
return data
def notify_slack(data: dict) -> dict:
"""Node 3: simulate posting a Slack message."""
print(f"Slack: New lead - {data['name']}")
return data
def run_new_lead_workflow(trigger_data: dict) -> Execution:
"""The workflow: an ordered chain of nodes, with a logged execution."""
execution = Execution(workflow_name="new_lead_notification")
data = extract_lead(trigger_data)
execution.log_step("extract_lead", data)
data = add_row_to_sheet(data)
execution.log_step("add_row_to_sheet", data)
data = notify_slack(data)
execution.log_step("notify_slack", data)
execution.finish("success")
return execution
if __name__ == "__main__":
# Simulated Gmail trigger firing with a new lead
incoming_lead = {"name": "Jordan Lee", "email": "jordan@example.com"}
result = run_new_lead_workflow(incoming_lead)
assert result.status == "success"
assert len(result.steps) == 3
assert result.steps[0]["node"] == "extract_lead"
assert result.steps[-1]["data"]["name"] == "Jordan Lee"
print("Execution log:", result.steps)
Code Walkthrough
Executionmirrors n8n's execution log ā it records the workflow name, when it started, every step's output, and a final status, exactly like opening a failed execution in n8n's UI to see where it broke.extract_lead,add_row_to_sheet, andnotify_slackare each a node ā one isolated action with a single responsibility, no knowledge of what happens before or after it.run_new_lead_workflowis the workflow ā it chains the nodes in a fixed order and passes the return value of one node as the input to the next, mimicking n8n's left-to-right data flow.- The
incoming_leaddictionary being passed intorun_new_lead_workflowstands in for the trigger firing ā in n8n this would be Gmail detecting a new message and kicking off the run automatically. execution.log_stepafter every node call is what makes debugging possible later ā without it, a failure gives you no information about which step broke.
Dry Run
Trace run_new_lead_workflow({"name": "Jordan Lee", "email": "jordan@example.com"}):
Executionis created withstatus="running"and an emptystepslist.extract_leadruns, returning{"name": "Jordan Lee", "email": "jordan@example.com"}. Logged as step 1.add_row_to_sheetprints the simulated sheet write and returns the same dict unchanged. Logged as step 2.notify_slackprints the simulated Slack message and returns the dict. Logged as step 3.execution.finish("success")setsstatus = "success".- The function returns the
Executionobject with three logged steps, each showing the exact data at that point ā precisely what you'd see inspecting an n8n execution.
Complexity Analysis
Time complexity: O(k) per execution, where k is the fixed number of nodes in the workflow (here, k = 3). This is correct because each node runs exactly once per trigger event ā there's no branching or looping over the lead data itself, just a straight chain.
Space complexity: O(k) for storing the execution log, since one log entry is kept per node. This is correct because the log's size scales only with how many steps the workflow has, not with the size of the incoming data (assuming each node's output is roughly constant size).
Compare this to the brute-force manual process: time cost there is O(n) human-minutes across n leads, since a person repeats the full sequence every time. The automated workflow's O(k) cost is paid once per event and doesn't grow with human attention ā it grows with machine execution time, which is orders of magnitude cheaper.
Alternative Solutions
The most common alternatives developers evaluate are Zapier and Make ā and the meaningful difference isn't features, it's the pricing and ownership model.
- Zapier / Make (task-based pricing): You're charged per task executed. Run the same workflow a thousand times, and you pay for a thousand tasks. This scales badly for high-volume automations, and if the vendor changes pricing, you have no way to move your workflows elsewhere ā there's no server to take with you.
- n8n (workflow-based pricing, self-hostable): You're charged per workflow, not per run ā executing it once or ten thousand times costs the same. You can self-host on your own infrastructure and own everything, or use n8n's cloud offering to skip maintenance, and either way you can migrate your workflows out whenever you choose.
The lesson's framing is worth internalizing: integration counts (six thousand apps vs four hundred) are a distraction if the platform can effectively hold your automations hostage through pricing or lock-in. The real question to ask when choosing a tool is "can I leave?" ā and it's a question worth asking about any vendor dependency in your stack, not just automation tools.
Edge Cases
- Empty trigger data: What happens if a "new lead" event fires with a missing name or email? A production workflow needs a validation node before proceeding, or downstream nodes will silently write incomplete rows.
- Duplicate trigger fires: Some triggers (webhooks especially) can fire more than once for the same event. Without deduplication logic, you'd get duplicate Sheet rows and duplicate Slack pings.
- Trigger never fires: If the schedule or webhook is misconfigured, the workflow silently never runs ā this is why checking execution history regularly matters, not just when something visibly breaks.
- A node fails mid-chain: If "add row to sheet" succeeds but "notify Slack" fails (e.g., API rate limit), you get an inconsistent state ā the lead is logged but nobody's notified. The execution log is what lets you spot and reprocess this.
- High volume trigger bursts: A hundred leads arriving in the same minute ā the workflow needs to handle concurrent executions without stepping on shared resources like a rate-limited API.
Common Mistakes
- Building one giant workflow that does five unrelated jobs. Exactly the mistake called out in the lesson ā when it breaks, you can't isolate which piece failed. Keep workflows scoped to one job.
- Not checking execution logs after setup. A workflow can be "working" the first time you test it and then silently fail days later on an edge case you never hit during testing.
- Choosing the wrong trigger type. Using a scheduled trigger when you actually need instant reaction (or vice versa) either delays automations that should be immediate or wastes resources polling when nothing changed.
- Ignoring the pricing model until it's expensive. Task-based pricing tools feel cheap at low volume and become very expensive once a workflow scales ā evaluate cost at your target volume, not your current one.
- Skipping data validation between nodes. Assuming every upstream node's output is well-formed leads to downstream nodes failing on malformed or missing fields.
- Self-hosting without a maintenance plan. Owning your infrastructure means owning uptime, updates, and backups too ā going self-hosted without accounting for that trades vendor lock-in for a different kind of risk.
Interview Questions
- How would you design an idempotent workflow so retried trigger events don't create duplicate side effects?
- What's the tradeoff between a scheduled trigger and a webhook trigger for a given use case?
- How would you add error handling so a failure in one node doesn't leave downstream systems in an inconsistent state?
- How does workflow-based pricing change the cost model for a system with unpredictable or spiky traffic compared to task-based pricing?
- What would you log in an execution record to make a 2 a.m. failure debuggable without waking anyone up?
Similar Problems
- Designing an event-driven pipeline (systems design): Same core pattern ā a trigger/event source, a chain of processing steps, and observability into what ran. Understanding n8n's model translates directly to designing message-queue-based systems.
- Building a CI/CD pipeline: A pipeline is also triggered (on push), runs an ordered chain of steps (build, test, deploy), and needs execution logs (build logs) for debugging ā same shape, different domain.
- Writing a Unix pipeline (
cmd1 | cmd2 | cmd3): Each command is a node, the pipe is the workflow's data flow, and the shell's exit codes are a crude execution log.
Key Takeaways
n8n replaces manual, repetitive cross-app work with four composable ideas: a node is one action, a workflow is an ordered chain of nodes, a trigger starts the chain, and an execution proves it ran and shows exactly what data moved through it. The technical model is simple by design ā the real leverage is in the pricing and ownership story: paying per workflow instead of per task, and being able to self-host so you're never locked into a vendor's terms.
Watch the Video
For the full walkthrough with visuals of the workflow builder in action, watch the video here: {LINK}
About the Series
This lesson is part of Fun with Learning Technology, a series built for developers who want to actually understand the tools they use ā not just click through a UI tutorial, but grasp the underlying model well enough to debug it at 2 a.m. when something breaks. Future lessons in this n8n track will build a real workflow from scratch, layer in conditionals and error handling, and cover self-hosting.
Call To Action
If this helped you understand n8n, drop a like on the video and subscribe on YouTube ā the channel is small right now, and every subscribe genuinely moves the needle. For deeper written breakdowns like this one delivered straight to your inbox, subscribe to the Substack. And if you've got a question about triggers, workflows, or your own automation idea, drop it in the comments ā I read all of them and future lessons often come directly from what people ask.
Ready to try it yourself? Solve N8n problems with instant feedback in the practice sandbox.
Practice now ā


