·15 min read

n8n: A fair-code workflow automation platform (Sustainable License, 52k stars)

A fair-code workflow automation platform connecting 400+ services with AI-powered nodes for intelligent automation.

The Problem

Every organization runs on glue code. A customer signs up in Stripe, and someone needs to add them to Mailchimp, create a Slack notification, and insert a row in Google Sheets. A support ticket closes in Zendesk, and someone needs to update the CRM, send a satisfaction survey, and log the resolution time. These are not engineering problems — they are plumbing problems. But most teams solve them with engineering time anyway, because the alternatives are worse.

The incumbent solutions fall into two camps, both broken:

Camp 1: SaaS automation platforms (Zapier, Make). These are easy to start with but become prohibitively expensive at scale. Zapier counts every step in a multi-step workflow as a separate “task.” A 5-step workflow triggered 1,000 times consumes 5,000 tasks — not 1,000. At $448.50/month for 50,000 tasks, a medium-traffic business pays more for automation than for its CRM. And because your workflows live on someone else’s infrastructure, you have zero control over data residency, execution latency, or uptime SLAs.

Camp 2: Custom scripts. A Python script with webhooks, cron jobs, and API clients is flexible and free. But it is also fragile, unobservable, and unmaintainable by anyone but the author. When the script breaks at 2 AM, the person who wrote it is on vacation. When a new API version ships, the script silently fails. When the compliance team asks “who has access to this data pipeline,” there is no answer.

Dimension Zapier (Professional) Custom Scripts n8n (Self-Hosted)
Cost at 50K tasks/mo $448.50/mo Infrastructure only (~$15-40/mo) Infrastructure only (~$15-40/mo)
Setup time for simple workflow 5 minutes 2-4 hours 15-30 minutes
Multi-step task counting Yes (each step = 1 task) No (free) No (free)
Data residency control None (US-based) Full Full
AI/LLM integration GPT-4o-mini only Any model (manual) Any model (native nodes)
Error handling Retry only Custom (if implemented) Retry + error branches + error workflows
Audit trail Activity log Git (if set up) Full execution history + logs
Non-technical maintainability High None Medium (visual builder)
Self-hosting Not available N/A Docker, K8s, bare metal

Why this matters: The gap between “easy but expensive” and “cheap but fragile” is where most automation initiatives stall. Teams start with Zapier, hit the pricing wall at 10-20K tasks/month, and either pay the tax or build custom scripts that no one wants to maintain. n8n fills this gap with a visual workflow builder that runs on your infrastructure, costs nothing per execution, and supports AI-powered nodes for intelligent automation. It is not a compromise — it is a genuine third option.

The Investigation

n8n (pronounced “n-eight-n”) started in 2019 as a side project by Jan Oberhauser, a Berlin-based engineer who wanted a self-hostable alternative to Zapier. The name comes from “nodemation” — node-based automation. By mid-2026, it has grown to 191,000+ GitHub stars, 58,000 forks, and 430 contributors, making it the most popular self-hosted workflow automation platform on the planet.

Finding 1: The fair-code license is a deliberate tradeoff.

n8n uses the Sustainable Use License (SUL), not an OSI-approved open-source license. The SUL allows free use for internal business operations, personal projects, and non-commercial distribution. What it restricts is commercial hosting — you cannot run n8n as a paid service that competes with n8n Cloud. Enterprise features (SSO, LDAP, advanced permissions) are behind a separate Enterprise License.

This is not a licensing accident. It is a business model that funds 50+ full-time developers while keeping the core product free for self-hosters. The alternative — a fully open-source license with a hosted SaaS — would either require VC-scale burn rates (like GitLab) or a feature-gated enterprise edition that leaves the community version perpetually outdated (like Grafana). n8n’s approach is pragmatic: the community gets the full product for self-hosted use, and n8n GmbH makes money from cloud subscriptions and enterprise features.

What this means: If you are self-hosting n8n for internal use, the license is effectively free and unrestricted. If you are building a commercial automation service, you need the Enterprise license or a different tool. For 99% of teams, the SUL is not a constraint.

Finding 2: The AI agent node is the architectural differentiator.

In early 2026, n8n rebuilt its AI Agent node from the ground up. The new node supports structured tool calling with JSON schema validation, configurable max retry counts (default 3), ReAct execution mode with visible intermediate reasoning steps, and four memory management options (in-memory, Redis, Postgres, Motorhead). This is not a thin wrapper around an LLM API — it is a full agent runtime that can call any n8n workflow as a tool, manage conversation state across executions, and fall back to alternative models on failure.

The key insight: n8n’s AI agent is not a separate product. It is a node in the workflow builder, which means it can call any of the 400+ integrations as tools. Your AI agent can query Postgres, send Slack messages, create GitHub issues, and update Salesforce records — all through the same visual interface you use for non-AI workflows. This is the difference between “AI that can chat” and “AI that can act.”

What this means: n8n is the only workflow automation platform where AI agents are first-class citizens in the visual builder, not an afterthought bolted onto a separate AI product. If your automation strategy involves LLMs, n8n is the clear choice.

Finding 3: Queue mode makes production scaling possible.

n8n’s default execution mode runs workflows in the main process. This works for development and low-volume use, but it is single-threaded and blocks the UI during execution. For production, n8n supports queue mode: the main process enqueues jobs to Redis (via Bull), and worker processes pick them up and execute them asynchronously.

The architecture is straightforward but effective. A single n8n instance with queue mode and 4 workers handles 100-500 concurrent executions, or roughly 50,000 executions per day. Scaling beyond that means adding more workers (horizontal) or moving to Kubernetes with HPA. The bottleneck is always the database — Postgres must handle the write load from execution results, and at high throughput, connection pooling and query optimization become critical.

What this means: n8n scales from a single Docker container on a $5 VPS to a Kubernetes cluster handling millions of executions per day. The architecture is simple enough for a solo developer to deploy and robust enough for enterprise production use. The key is knowing when to switch from regular mode to queue mode — and the answer is “before you think you need to.”

The Solution

n8n is a TypeScript application (~500,000 lines across 30+ packages in a monorepo) that runs as a Node.js server with a Vue.js frontend. It connects to 400+ services through native nodes, supports JavaScript and Python code execution, and provides a visual canvas for building multi-step workflows.

┌──────────────────────────────────────────────────────────────────────────┐
│                          n8n Architecture                                 │
│                                                                           │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │                        Frontend (Vue.js)                             │  │
│  │  ┌─────────────┐  ┌──────────────┐  ┌─────────────┐  ┌──────────┐  │  │
│  │  │ Canvas UI   │  │ Node Editor  │  │ Execution   │  │ Workflow │  │  │
│  │  │ (spatial    │  │ (config      │  │ History     │  │ Library  │  │  │
│  │  │  flowchart) │  │  panel)      │  │ Viewer      │  │ (templates)│  │  │
│  │  └─────────────┘  └──────────────┘  └─────────────┘  └──────────┘  │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
│                                    │ REST API                              │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │                     Backend (Node.js + Express)                       │  │
│  │                                                                       │  │
│  │  ┌──────────────┐  ┌──────────────────┐  ┌────────────────────────┐  │  │
│  │  │ Workflow     │  │  Node Registry   │  │  Credentials Manager  │  │  │
│  │  │ Engine       │  │  (400+ native    │  │  (encrypted storage,  │  │  │
│  │  │ (execution   │  │   + community)   │  │   OAuth2, API keys)   │  │  │
│  │  │  loop)       │  └──────────────────┘  └────────────────────────┘  │  │
│  │  └──────┬───────┘                                                     │  │
│  │         │                                                              │  │
│  │  ┌──────▼──────────────────────────────────────────────────────────┐  │  │
│  │  │                    Execution Modes                               │  │  │
│  │  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │  │
│  │  │  │ Regular Mode │  │ Queue Mode   │  │ Multi-Main (Ent.)    │  │  │
│  │  │  │ (in-process) │  │ (Redis +     │  │ (leader election,    │  │  │
│  │  │  │              │  │  Workers)    │  │  HA webhooks)        │  │  │
│  │  │  └──────────────┘  └──────────────┘  └──────────────────────┘  │  │
│  │  └─────────────────────────────────────────────────────────────────┘  │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
│                                    │                                       │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │                    Data Layer                                        │  │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │  │
│  │  │ PostgreSQL   │  │ Redis (Bull) │  │ External Storage (S3,    │  │  │
│  │  │ (workflows,  │  │ (job queue,  │  │  filesystem, binary data) │  │  │
│  │  │  credentials,│  │  pub/sub)    │  │                          │  │  │
│  │  │  executions) │  └──────────────┘  └──────────────────────────┘  │  │
│  │  └──────────────┘                                                   │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────────┘

Here is what each layer does:

  • Frontend (Vue.js): The spatial canvas UI lets you arrange nodes freely, group them into labeled clusters, and color-code them by function. The node editor panel provides configuration forms for each node type. The execution history viewer shows every run with input/output data at each step. The workflow library stores templates and reusable patterns.

  • Backend (Node.js + Express): The workflow engine is the core — it traverses the node graph, executes each node in order, and handles branching, merging, and error paths. The node registry loads all installed nodes (native + community). The credentials manager encrypts API keys and OAuth tokens at rest using AES-256-GCM.

  • Execution Modes: Regular mode runs workflows in the main process (simple, no dependencies). Queue mode uses Redis + Bull to distribute work to worker processes (production, horizontally scalable). Multi-main mode (Enterprise) runs multiple main processes with leader election for high availability.

  • Data Layer: PostgreSQL stores workflows, credentials, execution data, and user accounts. Redis serves as the job queue in queue mode and handles pub/sub for real-time execution updates. External storage (S3-compatible or filesystem) stores binary data like files and images.

Setup

# Quick start with Docker (single container, regular mode)
docker run -d \
  --name n8n \
  -p 5678:5678 \
  -v ~/.n8n:/home/node/.n8n \
  -e N8N_SECURE_COOKIE=false \
  n8nio/n8n

# Production Docker Compose (queue mode, Postgres, Redis)
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: changeme
      POSTGRES_DB: n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass changeme
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n
    ports:
      - "5678:5678"
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: changeme
      EXECUTIONS_MODE: queue
      N8N_ENCRYPTION_KEY: generate-a-strong-32-byte-key-here
      N8N_CONCURRENCY_PRODUCTION_LIMIT: 10
      EXECUTIONS_DATA_SAVE_ON_SUCCESS: none
      EXECUTIONS_DATA_MAX_AGE: 720
      N8N_METRICS: true
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    volumes:
      - n8n_data:/home/node/.n8n

  n8n-worker:
    image: n8nio/n8n
    command: worker
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: changeme
      EXECUTIONS_MODE: queue
      N8N_ENCRYPTION_KEY: generate-a-strong-32-byte-key-here
      N8N_CONCURRENCY_PRODUCTION_LIMIT: 10
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

volumes:
  postgres_data:
  redis_data:
  n8n_data:
EOF

# Start the stack
docker compose up -d

# Scale workers dynamically
docker compose up -d --scale n8n-worker=5

Production-Grade Configuration

# .n8n.env — place alongside docker-compose.yml
# Database
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}

# Encryption (MUST be set, MUST be backed up)
N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY}

# Execution mode
EXECUTIONS_MODE=queue
N8N_CONCURRENCY_PRODUCTION_LIMIT=10

# Data retention
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=720  # 30 days
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none  # save only errors
EXECUTIONS_DATA_SAVE_ON_ERROR=all

# Security
N8N_SECURE_COOKIE=true
N8N_METADATA_USER_EMAIL=admin@example.com
N8N_METADATA_INSTANCE_ID=prod-us-east-1

# Monitoring
N8N_METRICS=true
N8N_METRICS_INCLUDE_DEFAULT_METRICS=true

# Scaling
N8N_GRACEFUL_SHUTDOWN_TIMEOUT=30000
N8N_PAYLOAD_SIZE_MAX=16

Code Walkthrough: The Workflow Execution Engine

The heart of n8n is the WorkflowExecute class in packages/core/src/execution-engine/workflow-execute.ts. Here is the simplified execution flow:

// Simplified from packages/core/src/execution-engine/workflow-execute.ts
class WorkflowExecute {
  private workflow: Workflow;
  private additionalData: IWorkflowExecuteAdditionalData;
  private mode: WorkflowExecuteMode;
  private runExecutionData: IRunExecutionData;

  async run(triggerData: ITriggerData): Promise<IRun> {
    // 1. Identify the starting node
    const startNode = this.workflow.getStartNode(this.mode);

    // 2. Initialize the execution stack
    const nodeExecutionStack: INodeExecutionStack[] = [{
      node: startNode,
      data: { main: [[{ json: triggerData }]] },
      source: null,
    }];

    // 3. Process nodes in topological order
    return this.processRunExecutionData(nodeExecutionStack);
  }

  private async processRunExecutionData(
    nodeExecutionStack: INodeExecutionStack[]
  ): Promise<IRun> {
    while (nodeExecutionStack.length > 0) {
      const executionEntry = nodeExecutionStack.shift()!;
      const { node, data } = executionEntry;

      // 4. Check for disabled nodes — pass data through
      if (node.disabled) {
        this.addChildNodesToStack(node, data, nodeExecutionStack);
        continue;
      }

      // 5. Check for pinned data (testing mode)
      if (this.hasPinnedData(node)) {
        const pinnedData = this.getPinnedData(node);
        this.addChildNodesToStack(node, pinnedData, nodeExecutionStack);
        continue;
      }

      try {
        // 6. Execute the node
        const nodeType = this.workflow.getNodeType(node);
        const result = await nodeType.execute.call(this, {
          node,
          data,
          workflow: this.workflow,
          additionalData: this.additionalData,
          runExecutionData: this.runExecutionData,
          mode: this.mode,
        });

        // 7. Handle multi-input nodes (merge, wait)
        if (result.waitingExecution) {
          nodeExecutionStack.push(executionEntry);
          continue;
        }

        // 8. Propagate output to downstream nodes
        this.addChildNodesToStack(node, result.data, nodeExecutionStack);
      } catch (error) {
        // 9. Handle errors: retry, continue-on-fail, error workflow
        if (this.shouldRetry(node, error)) {
          await this.retryNode(node, data, error);
        } else if (node.continueOnFail) {
          this.addChildNodesToStack(
            node,
            this.createErrorOutput(data, error),
            nodeExecutionStack
          );
        } else {
          throw error; // triggers error workflow
        }
      }
    }

    return this.buildRunResult();
  }
}

The AI Agent node execution is more complex — it wraps a LangChain agent runtime:

// Conceptual: AI Agent node execution
class AiAgentNode {
  async execute(context: INodeExecutionContext): Promise<INodeExecutionResult> {
    const { llm, tools, memory, prompt } = context.getNodeParameters();

    // 1. Initialize the LangChain agent
    const agent = new AgentExecutor({
      agent: new ReActAgent({
        llm: this.createLLM(llm),
        tools: tools.map(t => this.createTool(t)),
        memory: this.createMemory(memory),
      }),
      maxIterations: context.getNodeParameter('maxIterations', 10),
      handleParsingErrors: true,
    });

    // 2. Execute with streaming
    const result = await agent.invoke({
      input: prompt,
      chat_history: await memory.chatHistory.getMessages(),
    });

    // 3. Save conversation to memory
    await memory.chatHistory.addMessage(result);

    return { json: { response: result.output } };
  }
}

How to Use Effectively

Step 1: Design workflows as directed acyclic graphs

n8n workflows are DAGs (directed acyclic graphs). Each node receives input from upstream nodes, processes it, and passes output downstream. The canvas supports branching (IF/ELSE via the Switch node), merging (Merge node), and looping (Loop Over Items node). Design your workflow so that each node does exactly one thing — a Slack message node should not also transform data.

Step 2: Use sub-workflows for modularity

# Create a reusable sub-workflow for error handling
# 1. Create a workflow called "Error Handler"
# 2. Add an Error Trigger node
# 3. Add nodes to send Slack alert, log to database, notify on-call
# 4. In any other workflow, add the "Error Workflow" setting in workflow options
# 5. Select "Error Handler" as the error workflow

Sub-workflows are n8n’s equivalent of function calls. They let you define a workflow once and call it from multiple parent workflows. Use them for:

  • Error handling (one error workflow for all workflows)
  • Data enrichment (look up user details, enrich with geolocation)
  • Notification patterns (standardized Slack/email templates)
  • Authentication flows (refresh tokens, re-authenticate)

Step 3: Use the AI Agent node for intelligent routing

# AI Agent workflow pattern:
# 1. Webhook node (receives incoming support ticket)
# 2. AI Agent node with:
#    - LLM: Claude 3.5 Sonnet
#    - Tools: Search knowledge base (vector store), Create ticket (Linear), 
#             Send reply (Gmail), Escalate to human (Slack)
#    - Memory: Postgres (persistent across sessions)
#    - Prompt: "You are a support agent. Classify the ticket, search the
#              knowledge base for an answer, and either reply or escalate."
# 3. Switch node (route based on AI decision)
# 4. Gmail node (send reply) OR Slack node (escalate)

The AI Agent node is not a chatbot — it is a decision engine that can call any n8n integration as a tool. The key to making it work is writing clear tool descriptions so the agent knows when to use each one.

Step 4: Use the HTTP Request node for anything not natively supported

# HTTP Request node configuration for a custom API:
# Method: POST
# URL: https://api.example.com/v2/orders
# Authentication: OAuth2 (PKCE supported)
# Headers:
#   Content-Type: application/json
# Body (JSON):
#   {
#     "customer_id": "{{ $json.customer_id }}",
#     "items": "{{ $json.items }}",
#     "source": "n8n-workflow-{{ $workflow.id }}"
#   }
# Retry: 3 attempts, exponential backoff
# Error handling: Continue on fail, route to error branch

The HTTP Request node is the escape hatch. If n8n does not have a native node for your service, the HTTP Request node connects to any REST API with full OAuth2 support, retry logic, and request chaining.

Production pitfall: The HTTP Request node is powerful but untyped. Unlike native nodes, it does not validate response schemas. Always add a Code node after an HTTP Request to validate the response shape before passing data downstream. A malformed API response can silently corrupt an entire workflow.

Step 5: Use expressions for dynamic behavior

# n8n expressions use {{ }} syntax (Lodash-style)
# Access previous node output:
{{ $json.field_name }}
{{ $('NodeName').item.json.field_name }}

# Access workflow metadata:
{{ $workflow.id }}
{{ $workflow.name }}
{{ $execution.id }}
{{ $execution.mode }}

# Date/time operations:
{{ $now }}
{{ $today }}
{{ $fromAI('field_name') }}  # AI-determined value

# Conditional logic:
{{ $json.amount > 100 ? 'high_value' : 'standard' }}

# Environment variables:
{{ $env.MY_VARIABLE }}

Expressions are evaluated at runtime using n8n’s WorkflowDataProxy, which provides access to node outputs, workflow metadata, environment variables, and the $fromAI() function for AI-determined values.

Use Cases

1. Customer Support Ticket Triage with AI

When you’d use this: Your support team receives 200+ tickets per day across email, chat, and a web form. You need to classify, prioritize, and route each ticket to the right team — and ideally answer common questions automatically.

Why n8n fits: The AI Agent node can classify tickets by intent, search a vector store knowledge base for answers, and either reply automatically (for common questions) or create a ticket in Linear/Jira with the correct priority and assignee. The entire pipeline runs on your infrastructure — no customer data leaves your Postgres database. Real-world example: Delivery Hero eliminated 200 hours/month of manual work using n8n for support automation.

2. E-Commerce Order Processing Pipeline

When you’d use this: A customer places an order on your Shopify store. You need to charge their card (Stripe), update inventory (ERP), send a confirmation email, create a shipping label (ShipStation), and notify the warehouse (Slack) — all within 30 seconds.

Why n8n fits: n8n’s Shopify trigger node fires on new orders. A chain of native nodes handles payment, inventory, email, shipping, and Slack — all in a single workflow with error handling at every step. If Stripe declines the card, the workflow routes to a “payment failed” branch that sends a different email and skips shipping. The entire pipeline runs in under 10 seconds.

3. Data Synchronization Between SaaS Tools

When you’d use this: Your sales team uses HubSpot, your support team uses Zendesk, and your finance team uses QuickBooks. When a deal closes in HubSpot, you need to create the customer in QuickBooks and set up the support workspace in Zendesk.

Why n8n fits: n8n’s 400+ native integrations cover all three platforms. A webhook from HubSpot triggers a workflow that creates records in QuickBooks and Zendesk, with data transformation between schemas handled by the Code node. The workflow runs on a schedule (every 5 minutes) or on-demand via webhook. Error notifications go to a Slack channel.

4. AI-Powered Content Generation Pipeline

When you’d use this: Your marketing team needs to generate 50 product descriptions per week, each optimized for SEO, translated into 3 languages, and posted to your CMS.

Why n8n fits: A Google Sheets trigger reads new product rows. An AI Agent node (Claude 3.5 Sonnet) generates SEO-optimized descriptions. A Loop node iterates over target languages, calling a translation API for each. A WordPress node publishes each description as a draft. The entire pipeline runs unattended — the marketing team just adds rows to the spreadsheet.

5. DevOps Incident Response Automation

When you’d use this: Your monitoring system (Grafana, Datadog, or PagerDuty) fires an alert. You need to create a Jira ticket, post to the incident Slack channel, run a diagnostic script on the affected server, and page the on-call engineer — all within 60 seconds.

Why n8n fits: n8n’s webhook trigger receives alerts from any monitoring system. A Switch node routes by severity (critical, warning, info). A Code node runs diagnostic commands via SSH. A PagerDuty node pages the on-call engineer. A Slack node posts a thread with the diagnostic results. The entire workflow completes in under 30 seconds, and the execution history provides a full audit trail for post-mortems.

Cheat Sheet

Aspect Detail
Repository github.com/n8n-io/n8n
License Sustainable Use License v1.0 (fair-code, not OSI-approved)
Language TypeScript (~500,000 lines, monorepo with 30+ packages)
GitHub Stars 191,000+ (as of June 2026)
GPU Requirements None (API-based LLMs); optional for local models via Ollama
Setup Time 5 minutes (Docker); 30 minutes (production Docker Compose)
Native Integrations 400+ (plus unlimited via HTTP Request node)
AI/LLM Support OpenAI, Anthropic, Google Gemini, Mistral, Groq, Ollama, DeepSeek, Cohere, AWS Bedrock, Hugging Face, OpenRouter, X.AI Grok
Key Features AI Agent node, 400+ integrations, queue mode scaling, sub-workflows, code nodes (JS/Python), MCP support, error workflows, execution history, Git-based environments
Common Gotchas Forgetting to set N8N_ENCRYPTION_KEY (data loss on restart); using SQLite in production; not pruning execution data (DB bloat); running in regular mode at scale; not backing up encryption key
Best Models for AI Agent Claude 3.5 Sonnet, GPT-4o, Gemini 1.5 Pro
Cost (Self-Hosted, Light) $15-40/month (infrastructure only)
Cost (Self-Hosted, Heavy) $100-500/month (infrastructure + workers)
Cost (n8n Cloud, Pro) ~$60/month (50K executions)
Missing Features No native multi-region active-active; no HIPAA compliance; no free cloud tier; no 6,000+ app library (Zapier has this)

Vibe Coding Projects

Project 1: Personal Email Digest Bot

What it does: A daily email digest that scrapes your Gmail inbox, uses an AI agent to summarize important threads, extracts action items, and sends a Markdown summary to Slack every morning at 8 AM. The AI agent classifies emails by priority (urgent, important, newsletter, spam) and only includes the first two categories in the digest.

What you’ll learn: How to set up cron-triggered workflows, use the Gmail and Slack native nodes, configure the AI Agent node with a custom prompt, and handle pagination (Loop Over Items node) for large inboxes. You will also learn how to use the Code node for data transformation between the AI output and Slack message format.

Effort: 2-3 hours. Infrastructure cost: $0 (on existing n8n instance).

Project 2: Multi-Platform Social Media Scheduler

What it does: A content publishing pipeline that reads from a Google Sheet (one row per post: date, text, image URL, platform), generates platform-specific variants using an AI agent (different tone for LinkedIn vs Twitter vs Instagram), creates the posts via native nodes (LinkedIn, Twitter/X, Instagram), and logs the results back to the sheet. Includes error handling: if a post fails on one platform, the workflow retries twice and then logs the failure without affecting other platforms.

What you’ll learn: How to use the Google Sheets trigger (watch for new rows), configure the AI Agent node for content adaptation, use the Switch node for platform-specific routing, implement per-node retry with exponential backoff, and write results back to the source sheet for auditability.

Effort: 4-6 hours. Infrastructure cost: $0 (on existing n8n instance).

Project 3: RAG-Powered Internal Knowledge Base Chatbot

What it does: A Slack bot that answers employee questions by searching an internal knowledge base. When a user DMs the bot, an AI Agent node embeds the query, searches a Qdrant vector store containing company documentation, retrieves the top 3 relevant chunks, and generates a response with citations. The bot maintains conversation history in Postgres memory for follow-up questions. If the AI cannot answer confidently (confidence score below 0.7), it escalates to a human in the #help channel.

What you’ll learn: How to set up a vector store node (Qdrant or Pinecone), configure the document ingestion pipeline (load PDFs, split text, embed, store), use the AI Agent node with a retrieval-augmented generation (RAG) pattern, implement confidence-based escalation logic, and manage conversation memory across sessions.

Effort: 6-8 hours. Infrastructure cost: $10-20/month (Qdrant cloud or self-hosted vector store).

Problems Solved Efficiently

Problem Type Why n8n Fits When to Look Elsewhere
Simple 2-3 step integrations Fast setup, visual builder, 400+ native nodes Use Zapier for 8,000+ app coverage
Complex multi-branch workflows DAG-based canvas, Switch/Merge nodes, sub-workflows Use Make for more visual appeal
AI-powered automation Native AI Agent node, any LLM, tool calling Use LangChain directly for custom agent logic
High-volume data pipelines Queue mode, horizontal scaling, 220 execs/sec per instance Use Airbyte for ELT, Kafka for streaming
Compliance/air-gap Self-hosted, full data residency, SOC 2 (cloud) Use ActivePieces for MIT license
DevOps incident response Webhook triggers, error workflows, Slack/PagerDuty nodes Use PagerDuty native automation for on-call
Content generation pipelines AI Agent + Loop + CMS nodes, unattended execution Use Make for simpler content workflows
Enterprise SSO/SAML Enterprise license, LDAP, role-based access Use Okata Workflows for native identity integration

Architectural Tradeoffs

What we gained:

  • Self-hosting at any scale. n8n runs on your infrastructure — Docker, Kubernetes, or bare metal. No per-execution pricing, no data leaving your network, no third-party dependency for uptime. A 3-year TCO comparison: Zapier at 50K tasks/month costs ~$38,000; n8n self-hosted costs ~$9,200-14,800 (infrastructure + maintenance).

  • AI agents as first-class citizens. The AI Agent node is not a separate product or a thin API wrapper. It is a full LangChain-based agent runtime that can call any of the 400+ integrations as tools, manage conversation state across executions, and fall back to alternative models. This is the only platform where your AI agent can query Postgres, send Slack messages, and create GitHub issues through the same visual interface.

  • Full code flexibility. The Code node runs JavaScript (Node.js 20) or Python inline, with access to npm and PyPI packages. If the visual builder cannot express your logic, write code. This is the difference between “no-code” (limited by what the UI exposes) and “low-code” (the UI handles 90%, code handles the rest).

  • Git-based environments. n8n supports push-pull between dev, staging, and production environments using Git. Workflows are exported as JSON — they are version-controllable, reviewable in pull requests, and deployable through CI/CD pipelines. This is the only workflow automation platform that treats workflows as code.

  • Observability without third-party tools. Every execution is recorded with full input/output data at each node. The execution history viewer shows the exact data that flowed through each step. Prometheus metrics expose queue depth, execution duration, error rates, and worker utilization at /metrics.

What we sacrificed:

  • No OSI-approved open-source license. The Sustainable Use License is not open source by OSI standards. It restricts commercial hosting that competes with n8n Cloud. For most teams this is irrelevant, but for open-source purists or organizations with strict open-source policies, ActivePieces (MIT license) is the alternative.

  • Steeper learning curve than Zapier. n8n’s canvas is more powerful than Zapier’s linear builder, but it is also more complex. Non-technical users need 1-2 days to become productive. Zapier’s step-by-step wizard works out of the box for anyone who can fill out a form.

  • Smaller native integration library. 400+ native nodes vs. Zapier’s 8,000+ apps. The HTTP Request node covers the gap, but it requires understanding REST APIs, authentication, and response parsing. For long-tail integrations, Zapier wins on breadth.

  • Self-hosting requires ops expertise. A production n8n deployment needs Postgres, Redis, Docker, reverse proxy, TLS certificates, backups, and monitoring. Teams without DevOps experience should use n8n Cloud instead. The self-hosting savings come with operational overhead.

  • No free cloud tier. n8n Cloud starts at $24/month. ActivePieces offers 1,000 tasks/month free. Zapier offers 100 tasks/month free. If you want to evaluate the platform without paying, you must self-host.

  • No HIPAA compliance. n8n Cloud is SOC 2 certified but not HIPAA compliant. For healthcare workloads, you need to self-host and manage compliance yourself, or use Zapier (HIPAA available on Team+ plans).

The real lesson: n8n is the right choice when you value control, cost predictability, and AI integration over ease of setup and breadth of integrations. It is the automation platform for engineering teams who want to own their infrastructure. If your team is non-technical and your workflows are simple, Zapier is faster. If you are building automation that touches customer data, runs at scale, or involves AI decision-making, n8n is the only serious option.

Course-Style Deep Dive

How the Workflow Engine Works Under the Hood

The execution engine in packages/core/src/execution-engine/workflow-execute.ts is a topological graph walker. Here is the detailed lifecycle:

  1. Initialization. The WorkflowExecute class is instantiated with the workflow definition, execution mode (manual, trigger, webhook, etc.), and initial data. It identifies the start node — for trigger-based workflows, this is the trigger node; for webhook workflows, it is the webhook node.

  2. Node Execution Stack. The engine maintains a stack of { node, data, source } entries. It pops one entry, executes the node, and pushes the output to downstream nodes. This is a breadth-first traversal — all nodes at the current depth execute before moving to the next depth.

  3. Node Type Resolution. Each node has a type field (e.g., n8n-nodes-base.slack). The engine looks up the node type in the registry, which maps type names to INodeType implementations. Each implementation provides execute(), poll(), trigger(), or webhook() methods depending on the node category.

  4. Data Flow. Data flows through the graph as INodeExecutionData[][] — an array of arrays, where the outer array represents output branches (most nodes have one branch, the Switch node has multiple) and the inner array represents items. Each item has a json field (structured data) and optionally binary (files, images).

  5. Multi-Input Nodes. Nodes like Merge and Wait receive input from multiple upstream nodes. The engine tracks which inputs have arrived and only executes the node when all required inputs are present. This is implemented through a “waiting execution” pattern — the node is pushed back onto the stack until all inputs arrive.

  6. Error Handling. If a node throws, the engine checks three conditions in order:

    • Retry: If retryOnFail is enabled, the engine retries the node with exponential backoff (1s, 2s, 4s, 8s, up to maxTries).
    • Continue on fail: If continueOnFail is enabled, the engine creates an error output with the error message and passes it downstream.
    • Error workflow: If neither condition is met, the engine checks if the workflow has an error workflow configured. If so, it triggers the error workflow with the error context. If not, the execution fails.
  7. Execution Modes. The mode parameter controls behavior:

    • manual: Runs in the UI for testing, shows real-time node output
    • trigger: Runs automatically when a trigger fires
    • webhook: Runs when a webhook request arrives
    • retry: Re-runs a failed execution with the same input data
    • cli: Runs from the command line
    • error: Runs as an error workflow (limited node access)

Advanced Pattern 1: AI Agent with RAG and Human-in-the-Loop

// Conceptual: AI Agent workflow with RAG + human approval
// This is configured through the n8n UI, not written in code

// 1. Webhook trigger receives a support ticket
// 2. AI Agent node (Claude 3.5 Sonnet) with:
//    - System prompt: "You are a support agent. Answer questions using
//      the knowledge base tool. If you cannot answer confidently, ask
//      for human escalation."
//    - Tools:
//      a) Vector Store Tool (Qdrant) — search knowledge base
//      b) Create Ticket Tool (Linear) — create ticket if needed
//      c) Send Email Tool (Gmail) — reply to customer
//      d) Escalate Tool (Slack) — ask human for help
//    - Memory: Postgres (persistent across sessions)
//    - Guardrails: Input validation (PII masking), output filtering
//    - Human-in-the-loop: Require approval for ticket creation > $100
// 3. Switch node: route based on AI decision
//    - "answered" → Gmail node (send reply)
//    - "escalated" → Slack node (post to #support with context)
//    - "ticket_created" → Linear node (update ticket with AI notes)

The human-in-the-loop feature is critical for production AI workflows. It pauses execution at a configurable point and waits for a human to approve or reject the action. The approval request includes the full context — what the AI decided, what data it used, and what action it wants to take.

Advanced Pattern 2: Multi-Tenant Workflow Execution

For teams running n8n as an internal platform, the Projects feature provides collection-based access control:

# Project structure for multi-tenant n8n
# /projects
#   /engineering
#     - Deploy notification workflow
#     - Code quality check workflow
#   /marketing
#     - Social media scheduler
#     - Email campaign workflow
#   /support
#     - Ticket triage workflow
#     - Customer feedback collector
#   /finance
#     - Invoice processing workflow
#     - Expense report automation

# Each project has:
# - Its own set of workflows
# - Its own credentials (segregated by project)
# - Role-based access (admin, editor, viewer)
# - Shared workflows (cross-project, read-only)

Projects are n8n’s answer to multi-tenancy. Each project has isolated credentials, workflows, and execution history. Users can be members of multiple projects with different roles. This is essential for organizations where different teams manage their own automation but share a single n8n instance.

Production Considerations

Database connection pooling. At high throughput, Postgres connection exhaustion is the most common failure mode. Each worker opens multiple connections, and the default DB_POSTGRESDB_POOL_SIZE (2) is too low for production. Increase it:

DB_POSTGRESDB_POOL_SIZE=10
# Or set per-worker:
N8N_DATABASE_POSTGRESDB_POOL_SIZE=10

Execution data pruning. Execution data grows without bound. n8n stores the full input/output data for every node in every execution. At 10,000 executions/day with 10 nodes each, that is 100,000 node execution records per day. Enable pruning:

EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=720  # 30 days in hours
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none  # only save errors
EXECUTIONS_DATA_SAVE_ON_ERROR=all

Worker concurrency tuning. The default concurrency of 10 per worker is a good starting point, but it depends on the workload. Workflows that make HTTP requests (I/O-bound) can handle higher concurrency. Workflows that run code or process large datasets (CPU-bound) need lower concurrency. Monitor CPU and memory usage and adjust:

# I/O-heavy workloads: higher concurrency
N8N_CONCURRENCY_PRODUCTION_LIMIT=20

# CPU-heavy workloads: lower concurrency
N8N_CONCURRENCY_PRODUCTION_LIMIT=5

Encryption key management. The N8N_ENCRYPTION_KEY is used to encrypt credentials at rest. If you lose it, all stored credentials become unrecoverable. Store it in a secrets manager (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) and back it up with your database backups. n8n supports fetching secrets from external providers natively.

Monitoring with Prometheus. n8n exposes metrics at /metrics when N8N_METRICS=true:

# Key metrics to alert on:
# n8n_execution_queue_length — queue depth (alert if > 1000)
# n8n_execution_error_count — error rate (alert if > 1% of total)
# n8n_worker_concurrency — current concurrency (alert if near limit)
# n8n_execution_duration_seconds — p95 execution time (alert if > 60s)

The Results

Metric Before n8n After n8n Improvement
Cost at 50K tasks/month $448.50 (Zapier Professional) $15-40 (self-hosted infrastructure) 10-30x cheaper
Support ticket triage time 15 min/ticket (manual) 30 sec/ticket (AI agent) 30x faster
Multi-step workflow setup 2-4 hours (custom script) 15-30 min (visual builder) 4-8x faster
Error handling coverage Manual (if implemented) Automatic (retry + error branches + error workflows) Full coverage
Data residency control None (Zapier US-based) Full (self-hosted, any region) Complete control
AI integration capability GPT-4o-mini only (Zapier) Any LLM, any model, local or cloud Unlimited
Execution audit trail Activity log (30 days) Full execution history (configurable retention) Complete
Concurrent execution capacity 10-20 (Zapier) 100-500 (queue mode, 4 workers) 10-25x
Vodafone automation savings £2.2 million Documented case study
Delivery Hero hours saved 200 hours/month Documented case study

What this means for you: n8n is not a cheaper alternative to Zapier — it is a fundamentally different approach to automation. It trades ease of setup for control, cost predictability, and AI integration. If your automation needs are simple and your budget is flexible, Zapier is faster. If you are building automation that touches customer data, runs at scale, or involves AI decision-making, n8n is the only platform that gives you the architectural foundation to do it right.

What to Watch Out For

  1. Set N8N_ENCRYPTION_KEY before creating any credentials. This is the single most destructive mistake in n8n. If you start n8n without setting this environment variable, it generates a random key on first startup. If the container restarts and the key changes, all stored credentials become permanently unrecoverable. Set it once, back it up, never change it.

  2. Never use SQLite in production. n8n’s default database is SQLite, which works for local development but fails under concurrent write load. Production deployments must use PostgreSQL. The migration from SQLite to Postgres is not trivial — do it before you have data you cannot afford to lose.

  3. Enable execution data pruning from day one. Execution data grows without bound. A workflow that runs 1,000 times per day with 10 nodes generates 10,000 node execution records per day. Without pruning, your Postgres database will fill up in weeks. Set EXECUTIONS_DATA_PRUNE=true and EXECUTIONS_DATA_MAX_AGE=720 (30 days) before you start running production workflows.

  4. Switch to queue mode before you think you need it. Regular mode runs workflows in the main process. At 10-20 concurrent executions, the UI becomes unresponsive. At 50+, the process crashes. Queue mode adds Redis as a dependency but decouples execution from the UI. Switch to queue mode when you have more than 5 production workflows running on triggers.

  5. Test workflows with the “Execute Workflow” button before enabling triggers. The manual execution mode shows real-time node output and lets you inspect data at each step. Enable the trigger (cron, webhook, app event) only after you have verified the workflow produces correct output with test data.

  6. Use the Code node sparingly. The Code node is powerful but creates a maintenance burden. Every line of JavaScript or Python in a Code node is code that needs to be tested, reviewed, and debugged. If the visual builder can express the logic, use the visual builder. Reserve the Code node for transformations that genuinely cannot be expressed with built-in nodes.

  7. Back up your encryption key and database together. The encryption key and the database are a matched pair. Restoring the database without the encryption key is useless — all credentials are encrypted with that key. Store both in the same backup system, with the same retention policy.

Lesson 1: “We lost all our credentials twice before we learned to set N8N_ENCRYPTION_KEY explicitly. The first time was a container restart. The second was a migration to a new server. Both were entirely preventable.” — n8n community, r/selfhosted

Lesson 2: “The AI Agent node is incredible when it works, but it is not magic. You need to write good tool descriptions, set reasonable max iterations, and always have a fallback path. The agent will hallucinate tool calls if you let it.” — n8n community, r/n8n

Lesson 3: “We migrated from Zapier to n8n and saved $4,000/month. But the migration took 3 weeks, not 3 days. The workflows are more powerful, but they require more thought to design. The savings are real — the effort is also real.” — n8n community, Hacker News

Advice for Getting Started

  1. Start with the Docker quick start (single container, SQLite) to learn the interface. Build 2-3 test workflows. Break them. Fix them. Get comfortable with the canvas, expressions, and error handling.

  2. Before moving to production, set up the full Docker Compose stack with Postgres, Redis, and queue mode. Set N8N_ENCRYPTION_KEY explicitly. Enable execution data pruning. Configure Prometheus metrics.

  3. Build your first real workflow with a non-critical integration — a Slack notification, a Google Sheets log, a webhook receiver. Verify it works in manual mode. Then enable the trigger. Monitor the first 100 executions for errors.

  4. Use sub-workflows from day one. Even if you only have one workflow, create an error handler sub-workflow and attach it. The pattern costs 5 minutes to set up and saves hours of debugging when something breaks at 2 AM.

  5. When you add the AI Agent node, start with a simple prompt and one tool. Verify the agent calls the tool correctly. Add tools one at a time. Test each addition. The agent’s behavior changes non-linearly as you add tools — more tools means more decisions, which means more opportunities for wrong decisions.

  6. Join the n8n community forum and the r/n8n subreddit. The community is active and the maintainers are responsive. Most questions have been answered — search before posting.

  7. If you hit a wall with the visual builder, remember the HTTP Request node and the Code node. They are escape hatches, not crutches. Use them when you need them, but prefer native nodes and expressions for everything else.


Next in the Open-Source AI Tools Mastery series: ActivePieces

NL

Written by Nivant Labs Team

Engineer at Nivant Labs

Share this post