Mechanic looking under the hood of a truck at exposed engine gears in a warm workshop
All articles

How n8n Actually Works: A Technical Breakdown

Andrew Powers
Andrew Powers·· 5 min read

n8n is a workflow automation tool that looks simple on the surface. But the execution model doesn't match the visual model — and that gap causes problems.

n8n lets you build automations by connecting nodes on a visual canvas. Drag, drop, connect. It looks like data flows through your workflow in parallel, left to right.

It doesn’t work that way.

I read n8n’s source code to understand why some workflows break in weird ways. (There are also engineering limitations you should know about.) Here’s what actually matters.

The Editor is Just a Design Tool

The canvas in your browser is just for designing. When you click “Execute,” it packages your workflow as JSON and sends it to the server. The server runs everything. The editor just polls for results.

Why this matters: That “test” button is making a real server request. If your server is slow or overloaded, the editor feels slow — even though nothing’s wrong with your browser.

Nodes Run Sequentially, Not in Parallel

Your workflow might look parallel on the canvas, but execution is sequential. Node A finishes completely before Node B starts.

flowchart LR
    A([A runs]) --> B([A finishes]) --> C([B runs]) --> D([B finishes]) --> E([C runs])
    classDef default fill:#dbeafe,stroke:#3b82f6,color:#1e40af,stroke-width:2px

The engine walks your workflow like a checklist. It won’t start a node until all its inputs are ready.

Why this matters: A slow API call in Node 3 blocks everything after it. If you have independent operations, they still wait in line. The only way to get true parallelism is the SplitInBatches node, which creates separate execution branches.

Each Item Runs Separately

This is the biggest surprise for most people.

If 100 leads come into an HTTP Request node, n8n doesn’t batch them into one API call. It makes 100 separate calls — one per lead.

What You Might ExpectWhat Actually Happens
100 leads → 1 API call with array100 leads → 100 API calls
Batch processingItem-by-item processing
Fails togetherEach item succeeds or fails independently

Why this matters:

  • Rate limits hit fast. 100 leads = 100 API calls = you’re throttled.
  • One bad email doesn’t kill the batch. Item 47 can fail while 1-46 and 48-100 succeed.
  • Slow nodes multiply. A 200ms API call × 100 items = 20 seconds.

If you need true batching, use a Code node to aggregate items first.

Data Passes by Reference

No subprocesses. No serialization between nodes. When Node A finishes, its output object gets passed directly to Node B.

// Node A returns:
[{ json: { email: "[email protected]", score: 85 } }]

// Node B receives that exact object
// Access it with:
items[0].json.email // → "[email protected]"

The $json you reference in expressions? That’s literally items[currentIndex].json.

Why this matters:

  • Nodes share memory. You can pass large objects without performance penalty.
  • Mutations are dangerous. If Node B modifies $json.email, Node C sees the modified version. Clone data if you need the original.
  • Binary data (files, images) is handled separately — stored by reference, not copied.

Expressions Evaluate at Runtime

When you write {{ $json.email }}, that string sits in your workflow JSON until execution. The server evaluates it when the node runs.

The expression sandbox includes:

  • $json — current item
  • $input.first() / $input.last() / $input.all() — access other items
  • $node["NodeName"].json — grab output from a specific upstream node
  • $env — environment variables
  • Standard JS: .map(), .filter(), .toUpperCase(), ternaries

Why this matters: The preview in the editor uses sample data. If your real data has different shape (missing fields, different types), expressions fail at runtime — not design time. Test with real data.

Active Workflows Consume Resources

When you toggle a workflow “active,” n8n:

  • Registers webhook URLs (they stay registered until you deactivate)
  • Starts timers for schedules
  • Runs polling checks on intervals

These listeners run whether or not they receive data.

ScenarioResource Cost
50 active workflows with webhooks50 registered URLs, 50 event listeners
20 polling workflows at 5-min intervals240 polling operations per hour

Why this matters: “I’ll just leave it active” has a cost. Unused active workflows waste server resources and slow down workflows you actually need. Deactivate what you’re not using.

The Database Stores Everything

Every execution — inputs, outputs, errors — gets written to the database. Every node’s result. Every retry.

At low volume, this is fine. At high volume, it’s your bottleneck.

Why this matters:

  • Execution history fills up fast. 1,000 executions/day × 10 nodes × 30 days = 300,000 records.
  • Database performance affects UI responsiveness.
  • Prune old executions. Check Settings → Workflow → “Delete executions older than.”

Workers Scale Throughput, Not Isolation

n8n’s queue mode runs workers as separate processes that pull jobs from Redis. This is for handling more concurrent workflows, not for isolating failures.

flowchart LR
    A([Main Server]) --> B([Redis Queue]) --> C([Workers])
    classDef default fill:#dbeafe,stroke:#3b82f6,color:#1e40af,stroke-width:2px

A worker picks up a job, runs the entire workflow, stores results. If the worker crashes mid-execution, the job returns to the queue and another worker retries.

Why this matters:

  • Single-server n8n handles ~50-100 concurrent executions comfortably
  • Beyond that, add workers. Each handles 10 concurrent jobs by default.
  • Workers are stateless. Any worker can run any workflow. Don’t store anything locally.

What To Do About It

RealityWhat To Do
Sequential executionPut slow operations at the end, or use SplitInBatches
Item-by-item processingAdd delays between items for rate-limited APIs
Shared memoryClone objects if you need to preserve original data
Runtime expression evaluationTest with production-like data, not just the happy path
Database stores all resultsConfigure execution pruning before you hit scale
Active workflows consume resourcesDeactivate unused workflows

The visual canvas makes n8n approachable. But it hides these mechanics. A workflow that looks clean can still be slow, memory-hungry, or hitting rate limits — because the execution model doesn’t match the visual model. Understanding this is why error handling patterns matter so much. And why some teams are asking whether workflows themselves are becoming obsolete.

There’s a simpler way. OpenClaw replaces workflow graphs with a single AI agent — no nodes, no sequential execution, no rate limit headaches. Compare hosting options.