Complete Guide

n8n: The Complete Guide to Workflow Automation 2026

Automate business processes, data ops, and workflows without vendor lock-in. Low-code + code flexibility with n8n.

31 min read
Lucas Arlot
Updated Jan 8, 2026
n8n: The Complete Guide to Workflow Automation 2026

Let’s be honest:

Most automation tools lock you in. Monthly fees that scale with usage. Data stuck in someone else’s cloud. Zero control over what happens under the hood.

n8n flips that script.

It’s a workflow automation platform that you can self-host (for free) or run in the cloud. You get 400+ integrations, full code access when you need it, and complete ownership of your data.

In this guide, you’ll learn everything about n8n: from “what is this thing” to running production workflows that handle thousands of executions daily.

No fluff. No theory dumps. Just what works.


n8n in 2 Minutes: What It Is and Why Teams Are Switching

n8n (pronounced “n-eight-n”) connects your apps and automates workflows. Like Zapier—but you own everything.

Who’s using n8n right now?

  • Ops teams — killing manual copy-paste between tools
  • Growth & marketing — syncing leads, triggering campaigns, enriching data
  • Developers — building internal tools without spinning up a full backend
  • Data teams — lightweight ETL without the Airflow complexity

Why teams switch from Zapier/Make

Three reasons keep coming up:

1. Cost gets real at scale

Zapier charges per “task.” Run 10,000 tasks/month? That’s $400+. On n8n self-hosted, same volume costs you ~$20 in server fees.

2. “I need to write actual code here”

Zapier’s code steps are sandboxed. n8n gives you full JavaScript/Python access. Need to call an internal API? Parse weird XML? Loop through 500 items? No problem.

3. Data can’t leave our servers

Healthcare, finance, legal—some industries can’t send data through third-party clouds. n8n self-hosted runs 100% on your infrastructure.

The trade-off: n8n has a learning curve. The UI is powerful but dense. Give yourself 2-3 hours to get comfortable. After that, you’ll wonder how you lived without it.


Real Use Cases (Steal These Ideas)

Here’s what teams actually build with n8n. Not theory—working automations you can replicate.

Notifications & Incident Response

Trigger: Error in your app, threshold crossed, or form submitted.
Flow: Slack alert → create Jira ticket → page on-call if critical.
Why n8n: Custom routing logic. “If P1, ping #incidents AND call PagerDuty. If P3, just log it.”

CRM & Sales Ops

Trigger: New lead in Typeform, HubSpot, or webhook.
Flow: Enrich with Clearbit → score → route to right sales rep → add to sequence.
Why n8n: Full control over lead scoring rules. No “upgrade to access this feature.”

E-commerce Automation

Trigger: New order, stock change, or abandoned cart.
Flow: Sync inventory to 3 channels → update prices → trigger fulfillment.
Why n8n: Handle thousands of SKU updates without per-task pricing killing you.

Data Sync & Mini-ETL

Trigger: Schedule (hourly/daily) or webhook.
Flow: Pull from API → transform → push to Google Sheets, Postgres, or warehouse.
Why n8n: Cleaner than scripts, simpler than Airflow, cheaper than Fivetran.

AI-Powered Workflows

Trigger: New email, support ticket, or document uploaded.
Flow: Send to OpenAI → classify/summarize → route or respond automatically.
Why n8n: Chain multiple AI calls, add human-in-the-loop, keep prompts versioned.

Pro tip: Start with ONE workflow. Get it running in production. Then expand. Most failed n8n projects try to automate everything at once.


Core Concepts (Know These Before Building)

Before you build your first workflow, nail these four concepts. Skip this section and you’ll waste hours debugging issues that have nothing to do with your logic.

Workflows, Nodes, Triggers, Executions

Workflow = your automation. A canvas where you connect nodes that do things.

Node = one step in your automation. Each node performs a single action: send an email, query a database, transform data, call an API.

Trigger = the node that starts your workflow. Two types:

  • Webhook triggers wait for an incoming HTTP request (form submission, Stripe event, custom call)
  • App triggers poll or listen to an app (new Gmail, new Slack message, new row in Airtable)

Execution = one run of your workflow from start to finish. n8n logs every execution so you can debug, replay, or audit later.

Mental model: Think of it like a recipe. The workflow is the recipe. Nodes are the steps. The trigger is what makes you start cooking (hunger, dinner party, etc.). Each time you cook = one execution.

Data Flow: Items, JSON, and Mapping

Here’s where n8n gets powerful—and where most beginners get stuck.

Everything in n8n is JSON. When a node runs, it outputs data as JSON objects. The next node receives that data and can use it.

Items = individual pieces of data flowing through your workflow. If you query a database and get 50 rows, you have 50 items. Each item passes through subsequent nodes.

Mapping = pulling data from previous nodes into the current one. Instead of hardcoding values, you reference them: {{ $json.email }} grabs the email field from the incoming data.

// Example: incoming data from a webhook
{
  "name": "John",
  "email": "john@example.com",
  "company": "Acme Inc"
}

// Reference in next node
{{ $json.name }}  → "John"
{{ $json.email }} → "john@example.com"

The key insight: Data flows left-to-right. Each node transforms or routes items. If something’s wrong, check what data is actually arriving at each step (n8n shows this in the execution log).

Credentials: Connect Apps Without Exposing Secrets

Credentials store your API keys, OAuth tokens, and passwords. You create them once, then reuse across workflows.

Why this matters:

  • Secrets are encrypted at rest
  • You don’t copy-paste API keys into every workflow
  • Changing a credential updates all workflows using it
  • Team members can use credentials without seeing the actual values

Common credential types:

  • API Key — simple key/secret pair
  • OAuth2 — redirects to the app for authorization (Google, Slack, HubSpot)
  • Basic Auth — username/password
  • Header Auth — custom headers for APIs that don’t fit other patterns

Security note: On self-hosted n8n, credentials are encrypted with your N8N_ENCRYPTION_KEY. Lose that key = lose access to all stored credentials. Back it up.

Environments: Dev vs Prod, Versions, Export/Import

n8n doesn’t have built-in environment separation. But you need it. Here’s how teams handle this:

Option 1: Separate instances
Run two n8n installations—one for development, one for production. Build and test in dev, then export the workflow JSON and import to prod.

Option 2: Workflow tags + naming conventions
Prefix workflow names: [DEV] Lead enrichment vs [PROD] Lead enrichment. Not ideal, but works for small teams.

Option 3: Git-based version control (recommended)
Export workflows as JSON, store in Git. Track changes, review before deploying, roll back if needed. This is how serious teams manage n8n at scale.

Export/Import workflow:

  1. In n8n, select workflow → Download → saves as .json
  2. Commit to Git with a descriptive message
  3. On prod instance: Import → upload the JSON
  4. Activate the workflow

Watch out for: Credentials don’t export. After importing a workflow, you’ll need to re-link credentials on the new instance.


Cloud vs Self-Hosted: Which One’s Right for You?

You’ve got two paths. Both work. The right choice depends on your constraints, not on what’s “better.”

Choose n8n Cloud if…

  • You want to start today. Sign up, build, deploy. No server setup, no Docker, no maintenance.
  • Your team isn’t technical. Cloud handles updates, backups, SSL, scaling. You focus on workflows.
  • You need collaboration features. Multiple users, shared credentials, workflow permissions—built in.
  • Budget is predictable. Pay per execution. Know your costs upfront.

Cloud makes sense for: marketing teams, small ops teams, agencies, anyone who values speed over control.

Choose Self-Hosted if…

  • Data can’t leave your infrastructure. Healthcare, finance, legal—compliance often requires on-prem.
  • You need internal network access. Connect to databases, APIs, or services that aren’t exposed to the internet.
  • Volume is high and budget matters. At 50,000+ executions/month, self-hosting costs a fraction of Cloud.
  • You want full control. Custom domains, your own backup strategy, specific n8n versions, no vendor dependency.

Self-hosted makes sense for: dev teams, companies with infra capabilities, regulated industries, high-volume use cases.

The Decision Checklist

Ask yourself these five questions:

QuestionCloudSelf-Hosted
Do I have someone to manage a server?No → CloudYes → Either
Does data need to stay on my network?No → CloudYes → Self-host
Will I run 50k+ executions/month?No → CloudYes → Self-host
Do I need internal API/DB access?No → CloudYes → Self-host
Do I need to start in < 1 hour?Yes → CloudNo → Either

Still unsure? Start with Cloud. You can always migrate to self-hosted later—workflows export as JSON, so nothing’s locked in.

Pricing reality check: Cloud’s free tier gives you 2,500 executions/month. Starter is €20/month for 10k executions. Self-hosted costs whatever your server costs (€5-20/month on Hetzner, DigitalOcean, etc.) with unlimited executions.


Skip the 47-step tutorials. Here’s how to get n8n running in minutes.

Local Testing (Docker or npm)

Docker (recommended) — one command, done:

docker run -it --rm --name n8n -p 5678:5678 n8nio/n8n

Open http://localhost:5678. You’re in.

Data won’t persist after you stop the container. That’s fine for testing. For persistence, add a volume:

docker run -it --rm --name n8n -p 5678:5678 \
  -v n8n_data:/home/node/.n8n \
  n8nio/n8n

npm (if you don’t have Docker):

npx n8n

Requires Node.js 18+. Same deal: http://localhost:5678.

Production Server with Docker Compose

For real deployments, use Docker Compose. This setup includes PostgreSQL (recommended over SQLite for production) and persistent storage.

Create a docker-compose.yml:

version: '3.8'

services:
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=n8n.yourdomain.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.yourdomain.com/
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres

  postgres:
    image: postgres:15
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  n8n_data:
  postgres_data:

Create a .env file (don’t commit this):

POSTGRES_PASSWORD=your-secure-password-here
N8N_ENCRYPTION_KEY=your-32-char-encryption-key

Generate a proper encryption key:

openssl rand -hex 16

Start everything:

docker compose up -d

Essential Environment Variables

These are the variables that actually matter. Skip the rest until you need them.

VariableWhat it doesExample
N8N_HOSTYour domain (required for webhooks)n8n.yourdomain.com
N8N_PROTOCOLhttp or httpshttps
WEBHOOK_URLFull URL for incoming webhookshttps://n8n.yourdomain.com/
N8N_ENCRYPTION_KEYEncrypts credentials. Back this up.32-char hex string
N8N_BASIC_AUTH_ACTIVEEnable login protectiontrue
N8N_BASIC_AUTH_USERUsernameadmin
N8N_BASIC_AUTH_PASSWORDPasswordsecure-password

For reverse proxy (Nginx/Traefik): Make sure to forward the Host header and enable WebSocket proxying. n8n needs both for the editor to work properly.

Production checklist:
✅ PostgreSQL instead of SQLite
✅ Encryption key backed up securely
✅ HTTPS via reverse proxy
✅ Basic auth or SSO enabled
✅ Regular backups of database + n8n_data volume


Your First Workflow from A to Z

Time to build something real. We’ll create a webhook that receives form data, validates it, and sends a Slack notification. Classic pattern, infinite variations.

Example: Webhook → Process → Action

Step 1: Create a new workflow

Click “Add workflow” in n8n. Name it something useful: Contact Form → Slack.

Step 2: Add a Webhook trigger

  1. Click the + button
  2. Search for “Webhook”
  3. Select Webhook node
  4. Set HTTP Method to POST
  5. Copy the “Test URL” (you’ll need this)

Your webhook is now listening. It looks like:
https://your-n8n.com/webhook-test/abc123

Step 3: Test with sample data

Send a test request (use curl, Postman, or your browser console):

curl -X POST https://your-n8n.com/webhook-test/abc123 \
  -H "Content-Type: application/json" \
  -d '{"name": "John", "email": "john@example.com", "message": "Hello!"}'

Click “Execute workflow” in n8n. You should see the incoming data in the Webhook node output.

Step 4: Add validation (IF node)

  1. Add an IF node after the Webhook
  2. Condition: {{ $json.email }} → “is not empty”
  3. This creates two branches: true (valid) and false (invalid)

Step 5: Send to Slack

  1. On the “true” branch, add a Slack node
  2. Connect your Slack credentials (OAuth2)
  3. Select channel, compose message:
New contact form submission!
Name: {{ $json.name }}
Email: {{ $json.email }}
Message: {{ $json.message }}

Step 6: Activate

Toggle the workflow to “Active.” Your test URL becomes a production URL. Done.

The n8n Dev Loop: Test, Replay, Activate

This is how you’ll spend most of your time in n8n:

1. Build with test data
Use “Execute workflow” to run with sample data. Each node shows its input/output—click to inspect.

2. Pin data for iteration
Right-click a node → “Pin data.” Now that node always outputs the same data while you build downstream logic. Huge time saver.

3. Replay executions
Go to “Executions” tab. Click any past run to see exactly what happened. Click “Retry” to run it again with the same input.

4. Debug with execution log
Something broke? The execution log shows every node, its input, output, and any errors. No guessing.

5. Activate when ready
Only active workflows respond to triggers. Keep it inactive while building, activate when tested.

Pro tip: Use “Execute workflow” with the webhook node selected—n8n will wait for an incoming request, letting you test with real data from your actual form/app.

Best Practices: Naming, Folders, Comments

Your future self will thank you. So will your teammates.

Naming conventions:

  • Workflows: [Team] Action - Source → Destination
    Examples: [Sales] New Lead - Typeform → HubSpot, [Ops] Daily Report - DB → Slack

  • Nodes: Describe what they do, not what they are
    IF, HTTP Request, Code
    Check if email valid, Fetch user from API, Format message

Use folders:

Group workflows by team, project, or function. n8n supports folders—use them before you have 50 workflows in a flat list.

Add sticky notes:

The yellow sticky note node is documentation. Use it to explain:

  • Why this workflow exists
  • What triggers it
  • Any gotchas or edge cases
  • Who to contact if it breaks

Comment your code nodes:

If you’re writing JavaScript in a Code node, comment it. You’ll forget what it does in 3 months.

// Extract unique email domains from contact list
// Used for: lead segmentation by company
const domains = items.map(item => {
  const email = item.json.email;
  return email.split('@')[1];
});
return [...new Set(domains)].map(d => ({ json: { domain: d } }));

Mastering Expressions (n8n’s Superpower)

Expressions are what turn n8n from “connect two apps” into “build anything.” Once you get this, you’ll automate things you didn’t think possible.

Syntax, Editor, Variables

Opening the expression editor:
Click any input field → click the fx button (or press /). You’re now in expression mode.

Basic syntax:
Everything inside {{ }} is evaluated as JavaScript.

{{ $json.email }}                    // Get email from current item
{{ $json.name.toUpperCase() }}       // Transform to uppercase
{{ $json.price * 1.2 }}              // Math operations
{{ $json.items.length }}             // Array length

Key variables you’ll use constantly:

VariableWhat it gives you
$jsonCurrent item’s data
$inputAll items from previous node
$node["NodeName"]Output from a specific node
$workflowWorkflow metadata (id, name)
$executionCurrent execution info
$nowCurrent timestamp (Luxon DateTime)
$todayToday at midnight (Luxon DateTime)

Accessing nested data:

{{ $json.user.address.city }}        // Dot notation
{{ $json["field-with-dashes"] }}     // Bracket notation for special chars
{{ $json.items[0].name }}            // Array access

Tournament Mode, Dates (Luxon), and JSON Queries (JMESPath)

Tournament mode explained:

When a node outputs multiple items, expressions run once per item. But what if you need data from item #3 while processing item #1?

That’s where $input.all() and $input.item come in:

{{ $input.all()[2].json.email }}     // Get email from 3rd item
{{ $input.first().json.name }}       // First item's name
{{ $input.last().json.id }}          // Last item's id
{{ $input.item.json.email }}         // Current item (same as $json)

Dates with Luxon:

n8n uses Luxon for dates. Stop fighting with JavaScript Date objects.

{{ $now.toISO() }}                          // 2024-01-15T14:30:00.000Z
{{ $now.toFormat('yyyy-MM-dd') }}           // 2024-01-15
{{ $now.minus({ days: 7 }).toISO() }}       // 7 days ago
{{ $now.startOf('month').toISO() }}         // First day of current month
{{ DateTime.fromISO($json.date).toFormat('dd/MM/yyyy') }}  // Parse & format

Common patterns:

  • $now.minus({ hours: 24 }) — last 24 hours
  • $today.startOf('week') — start of this week
  • $now.diff($json.createdAt, 'days').days — days since creation

JMESPath for complex queries:

When you need to filter or transform arrays without Code nodes:

{{ $jmespath($json.users, "[?age > `30`].name") }}  // Names of users over 30
{{ $jmespath($json.items, "[*].price | sum(@)") }} // Sum all prices
{{ $jmespath($json.data, "[?status == 'active']") }} // Filter active items

Practical Patterns: Fallback, Safe Access, Formatting, Filtering

These patterns solve 90% of real-world expression problems.

Fallback values (handle missing data):

{{ $json.nickname || $json.name || "Anonymous" }}
{{ $json.phone ?? "No phone provided" }}

Safe access (prevent crashes on undefined):

{{ $json.user?.address?.city || "Unknown" }}     // Optional chaining
{{ $json.items?.[0]?.name }}                     // Safe array access

String formatting:

{{ $json.name.trim() }}                          // Remove whitespace
{{ $json.email.toLowerCase() }}                  // Lowercase
{{ $json.description.slice(0, 100) + "..." }}    // Truncate
{{ $json.tags.join(", ") }}                      // Array to string

Number formatting:

{{ $json.price.toFixed(2) }}                     // 2 decimal places
{{ Math.round($json.score) }}                    // Round
{{ ($json.amount / 100).toLocaleString('en-US', {style: 'currency', currency: 'USD'}) }}

Conditional logic:

{{ $json.status === "active" ? "✅ Active" : "❌ Inactive" }}
{{ $json.score >= 80 ? "Pass" : "Fail" }}

Quick filtering in expressions:

{{ $json.items.filter(i => i.price > 100) }}     // Filter expensive items
{{ $json.users.find(u => u.role === "admin") }}  // Find first admin
{{ $json.tags.includes("urgent") }}              // Check if tag exists

When to use Code node instead: If your expression is longer than one line, or you need loops with side effects, switch to a Code node. Expressions are for transformations, not business logic.


Reliability: Errors, Retries, Alerting

Your workflow runs perfectly. You deploy it. Day three—silence. You check: the API has been returning 500 for 72 hours. Nobody noticed.

This isn’t an edge case. This is the default if you don’t set up error handling.

Error Workflow: Centralize All Failures

n8n lets you create one Error Workflow that catches failures from all your other workflows. Set it up once, forget about individual error handling.

Setup (5 minutes):

  1. New workflow → [System] Error Handler
  2. Add an Error Trigger node (not Webhook)
  3. Connect to Slack/Email/DB

The Error Trigger receives everything you need:

{
  "workflow": { "name": "Lead Sync to HubSpot" },
  "execution": {
    "url": "https://n8n.domain.com/execution/231",
    "error": { "message": "Status 500", "node": "HTTP Request" }
  }
}
  1. In each important workflow’s Settings → Error Workflow → select your Handler

Slack template:

🚨 {{ $json.workflow.name }} — FAILED
Node: {{ $json.execution.error.node }}
{{ $json.execution.error.message }}
→ {{ $json.execution.url }}

Every error, one place. No more surprises.

Stop And Error: Force a Failure

API returns 200, but the data is empty. n8n thinks the workflow “succeeded.” You know it didn’t.

Stop And Error node tells n8n: “This is an error. Mark as failed. Trigger the Error Workflow.”

IF node: $json.results.length === 0
    ↓ True
Stop And Error: "API returned 0 results — likely rate limited"

When to use:

  • API 200 + empty response
  • Business rule violated (duplicate, missing field)
  • Rate limit hit — you don’t want partial data

Strategies: Retry, Backoff, Idempotency

Retry on Fail

Every node → Settings → Retry on Fail.

SettingRecommendation
Wait1000–5000ms
Max Retries3 (more = needs intervention)

Exponential Backoff

For APIs with rate limits—fixed wait doesn’t help. Increase exponentially:

const attempt = $json.attemptCount || 1;
const waitMs = Math.min(1000 * Math.pow(2, attempt), 30000);
// 1s → 2s → 4s → 8s → max 30s

Idempotency

Retry = potential duplicate. Protect yourself:

// Generate unique key
const idempotencyKey = `${$json.email}-${$json.orderId}`;
// Check if exists before INSERT
// Or use UPSERT operations

Dead-Letter Queue

Item fails 3+ times? Stop retrying. Log it for manual review:

IF: attemptCount > 3
  → True: Add to "Failed Items" sheet
  → False: Continue normally

Review weekly. Dead-letter items reveal systemic problems.

Proactive Monitoring

Don’t wait for failure. Alert on:

  • Workflow hasn’t run in 24h (heartbeat check)
  • Success rate < 90% for last 100 executions
  • Execution time 2x above normal

Reality: Production problems are rarely crashes. They’re silent: empty responses, stopped webhooks, rate limits eating 30% of your data. Monitoring catches them. Hope doesn’t.


Security & Governance

n8n workflows often touch sensitive data: API keys, customer emails, payment info. A misconfigured instance is an open door.

This section isn’t optional. It’s the difference between “automation tool” and “security incident.”

The Basics: Lock It Down

HTTPS everywhere. No exceptions. Use a reverse proxy (Nginx, Traefik, Caddy) with Let’s Encrypt.

# Nginx minimal config
server {
    listen 443 ssl;
    server_name n8n.yourdomain.com;
    
    ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;
    
    location / {
        proxy_pass http://localhost:5678;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Authentication options:

MethodWhen to UseSetup Complexity
Basic AuthSolo/small team, quick setupLow
SSO (SAML/OIDC)Enterprise, existing IdPMedium
LDAPCorporate environmentsMedium

Basic Auth env vars:

N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=use-a-strong-password

2FA: Available on n8n Cloud and Enterprise. For self-hosted Community, SSO with 2FA-enabled IdP is your path.

Reduce attack surface:

  • Don’t expose n8n directly to internet. Use VPN or IP whitelist.
  • Disable public API if you don’t need it: N8N_PUBLIC_API_DISABLED=true
  • Run n8n as non-root user (Docker default does this)
  • Limit outbound network if possible (firewall rules)

Patching: The Boring Part That Saves You

n8n has had critical vulnerabilities. Every automation platform has. The question is: how fast do you patch?

Real example: In early 2024, a critical RCE vulnerability (CVE-2024-xxxx) allowed authenticated users to execute arbitrary code. Fixed in hours, but instances that hadn’t updated were exposed.

Your patching routine:

  1. Subscribe to releases: Watch the n8n GitHub repo or follow @naborso
  2. Test before prod: Update staging first, verify workflows still work
  3. Automate updates: Use Watchtower for Docker or scheduled CI/CD
# Watchtower auto-updates (use with caution in prod)
docker run -d \
  --name watchtower \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower n8n --interval 86400

Rule of thumb: Security patches within 48h. Feature updates within 2 weeks.

Credentials & Secrets: Handle With Care

n8n encrypts credentials at rest using N8N_ENCRYPTION_KEY. This is non-negotiable.

If you lose this key, you lose all stored credentials. No recovery. Backup it separately from your database.

Best practices:

# Generate a strong key
openssl rand -hex 32

# Store it outside your repo
# Use environment variables, not config files
N8N_ENCRYPTION_KEY=your-64-char-hex-key

Credential rotation:

Most teams forget this. APIs get compromised. Employees leave. Rotate credentials:

  • Quarterly: High-risk credentials (payment APIs, admin tokens)
  • Annually: Lower-risk credentials (analytics, newsletters)
  • Immediately: When employee with access leaves

RBAC (Role-Based Access Control):

Available on n8n Cloud Team/Enterprise and self-hosted Enterprise.

RoleCan Do
OwnerEverything
AdminManage users, all workflows
MemberOwn workflows, shared workflows
ViewerRead-only (audit, reporting)

For Community self-hosted: one instance = one user level. Separate instances for different access levels if needed.

Audit trail: Enterprise plans log who did what. For Community, enable execution logging and monitor access logs from your reverse proxy. Not perfect, but better than nothing.


Production: Performance, Observability, Scaling

Your n8n instance works great with 100 executions/day. Then you hit 10,000. Suddenly workflows timeout, the UI crawls, and you’re debugging at 2am.

Scale before you need to. Here’s how.

Performance: Where It Breaks First

Database is usually the bottleneck. SQLite works for testing. PostgreSQL is mandatory for production.

# Switch to Postgres (docker-compose.yml)
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_DATABASE=n8n

Execution data piles up. By default, n8n keeps all execution history. At scale, this kills performance.

# Prune old executions
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168  # hours (7 days)
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none  # aggressive, but fast

Memory matters. Default Node.js memory limit is ~1.5GB. Heavy workflows need more:

NODE_OPTIONS=--max-old-space-size=4096  # 4GB

Quick wins:

ProblemFix
Slow UIPrune executions, add PostgreSQL indexes
Workflow timeoutsIncrease EXECUTIONS_TIMEOUT (default 3600s)
Webhook delaysUse queue mode (see Scaling below)
Memory spikesSplit large workflows, process in batches

Observability: Know Before It Breaks

Execution logs are your source of truth. n8n stores every run with input/output data. Use it.

  • Success rate trending down? API changed, credentials expired, or rate limit hit.
  • Execution time increasing? Upstream service degrading or data volume growing.
  • Specific node failing? Usually credentials or API format change.

External monitoring setup:

  1. Health endpoint: GET /healthz returns 200 if n8n is up
  2. Uptime monitoring: Point Uptime Robot, Pingdom, or Better Stack at it
  3. Alerting: Connect your Error Workflow to PagerDuty/Opsgenie for critical workflows

Metrics to track:

# Enable Prometheus metrics (self-hosted)
N8N_METRICS=true
N8N_METRICS_PREFIX=n8n_
# Scrape from /metrics endpoint

Key metrics:

  • n8n_workflow_executions_total — execution count by status
  • n8n_workflow_execution_duration — how long workflows take
  • n8n_api_requests_total — API load

Scaling: When One Instance Isn’t Enough

Queue mode is the first step. Instead of executing workflows immediately, n8n pushes jobs to a queue. Separate workers process them.

# Main instance (receives webhooks, queues jobs)
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis

# Worker instance(s) (processes jobs)
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis
N8N_DISABLE_UI=true  # workers don't need UI

When to use queue mode:

  • Webhook response time matters (queue mode responds instantly)
  • You need horizontal scaling (add workers, not bigger servers)
  • Workflows are CPU/memory intensive

Scaling strategy by volume:

Executions/daySetup
< 1,000Single instance, PostgreSQL
1,000–10,000Queue mode + 2-3 workers
10,000–100,000Queue mode + auto-scaling workers + Redis cluster
100,000+Contact n8n Enterprise or architect custom solution

Backups (don’t skip this):

# PostgreSQL daily backup
pg_dump -U n8n n8n > backup_$(date +%Y%m%d).sql

# n8n data volume (credentials, etc.)
docker run --rm -v n8n_data:/data -v $(pwd):/backup \
  alpine tar czf /backup/n8n_data_$(date +%Y%m%d).tar.gz /data

Automate this. Test restores quarterly. The backup you never tested is the backup that won’t work.

Reality check: Most teams don’t need queue mode until 5,000+ executions/day. Start simple. Add complexity when metrics demand it, not before.


License: Is n8n Really “Open Source”?

Short answer: No. But it’s close enough for most use cases.

n8n uses a Sustainable Use License (previously called “fair-code”). The source code is public on GitHub. You can read it, modify it, self-host it. But there are restrictions.

What You CAN Do

Self-host for your own business — Run n8n internally, automate your processes, no fees, no limits.

Modify the code — Fork it, customize nodes, build internal features. Your modifications stay yours.

Use commercially — Your company can use n8n to make money. Automating sales, ops, marketing? All good.

Contribute back — Submit PRs, report bugs, improve the platform. Community contributions are welcome.

What You CAN’T Do

Resell n8n — You can’t package n8n and sell it as your own product.

Offer n8n as a service — Hosting n8n for other companies (like your own “n8n Cloud”) requires a commercial license from n8n GmbH.

Remove license headers — The attribution must stay in the code.

Why This Matters

If you’re a company using n8n internally: you’re fine. Self-host, customize, scale. No licensing fees.

If you’re an agency building automations for clients: also fine. You’re using n8n to deliver services, not reselling the software itself.

If you’re thinking of building a product on top of n8n (SaaS, managed hosting): talk to n8n first. You’ll need a commercial agreement.

The “Fair-Code” Philosophy

n8n chose this model to stay sustainable. Pure open source projects often struggle with funding—companies use the software for free while a small team maintains it for nothing.

Sustainable Use License = source available + commercial restrictions on competing with n8n directly.

Whether you agree with this model or not, understand it before you build. The license is clear, and n8n has enforced it.

Bottom line: For 95% of users—internal automation, agencies, startups—the license changes nothing. Self-host freely. Just don’t try to become the next n8n Cloud without a conversation first.


Pricing: How to Estimate Cost (No Surprises)

n8n pricing confuses people. Cloud charges per execution. Self-hosted is “free” but costs server time. Let’s break it down.

n8n Cloud Pricing

PlanPriceExecutionsBest For
Free€02,500/monthTesting, personal projects
Starter€20/mo2,500 + €0.0035/extraSmall teams, low volume
Pro€50/mo10,000 + €0.0020/extraGrowing teams
EnterpriseCustomUnlimitedLarge orgs, compliance needs

What counts as an “execution”?

One workflow run = one execution. If your workflow processes 100 items, that’s still 1 execution. Sub-workflows count separately.

Estimate your monthly cost:

Monthly executions × Overage rate + Base price = Total

Example: 25,000 executions on Pro plan
10,000 included + (15,000 × €0.002) = €50 + €30 = €80/month

Self-Hosted: The “Free” Option

No license fees. You pay for infrastructure:

ProviderSpecMonthly Cost
Hetzner CX212 vCPU, 4GB RAM~€6
DigitalOcean2 vCPU, 4GB RAM~$24
AWS t3.medium2 vCPU, 4GB RAM~$30
Your own serverVariesElectricity + time

Add PostgreSQL (required for production): +€5-15/month managed, or run it yourself.

Real cost comparison at 50,000 executions/month:

OptionMonthly Cost
n8n Cloud Pro€50 + (40k × €0.002) = €130
Self-hosted (Hetzner)€6 server + €5 DB = €11
Self-hosted (DigitalOcean)$24 + $15 DB = ~€35

Self-hosted wins on cost. Cloud wins on time. Your DevOps hours have a price too.

When to Upgrade (Decision Points)

Free → Starter: You need more than 2,500 executions or multiple active workflows.

Starter → Pro: Overages are eating your budget. At ~5,000 executions, Pro becomes cheaper.

Pro → Enterprise: You need SSO, audit logs, priority support, or your legal team requires a signed contract.

Cloud → Self-hosted:

  • You’re spending €100+/month on Cloud
  • You have DevOps capacity
  • Data residency matters

Hidden Costs to Watch

Cloud:

  • Overages sneak up. Set billing alerts.
  • Annual billing saves ~20%, but locks you in.

Self-hosted:

  • Server maintenance time (updates, backups, debugging)
  • Monitoring tools (Grafana, alerts)
  • Your time when it breaks at 2am

My take: Start with Cloud Free or Starter. Get your workflows working. Once you’re at €100+/month and have someone who can manage infrastructure, consider self-hosting. The math only works if you actually maintain it.


Alternatives to n8n (And When They Win)

n8n isn’t always the answer. Here’s an honest look at when competitors make more sense.

Quick Comparison

ToolBest ForPricing ModelSelf-Host
n8nTechnical teams, high volume, data controlFree self-hosted / Cloud per-execution✅ Yes
ZapierNon-technical users, quick setupPer-task (expensive at scale)❌ No
MakeVisual builders, mid-complexityPer-operation (cheaper than Zapier)❌ No
PipedreamDevelopers, code-firstGenerous free tier, per-credit❌ No
AirflowData engineering, DAGsFree (self-managed)✅ Yes

When Zapier Wins

Choose Zapier if:

  • Your team isn’t technical and won’t become technical
  • You need something working in 15 minutes
  • Volume stays under 1,000 tasks/month
  • Budget isn’t the constraint

Zapier’s UI is unmatched for simplicity. 5,000+ integrations. Zero learning curve. You pay for that convenience.

When Make Wins

Choose Make if:

  • You want visual building but more power than Zapier
  • Budget matters (Make is 4-5x cheaper per operation)
  • You need branching, iterations, error handling
  • Team can handle slightly more complexity

Make hits a sweet spot: more capable than Zapier, friendlier than n8n, reasonable pricing.

When Pipedream Wins

Choose Pipedream if:

  • You’re a developer who thinks in code
  • You want Node.js/Python with minimal abstraction
  • Generous free tier matters (10,000 credits/month)
  • You don’t need self-hosting

Pipedream is n8n’s closest competitor for technical users. Better DX for pure coders. But no self-hosting option.

When Airflow/Prefect Win

Choose Airflow or Prefect if:

  • You’re building data pipelines, not app integrations
  • Workflows are DAGs with complex dependencies
  • Your team already knows Python
  • You need serious scheduling and orchestration

These aren’t n8n competitors—they’re different tools. Airflow for data engineering. n8n for operational automation.

The Decision Framework

Ask yourself:

  1. Who will build and maintain this?

    • Non-technical → Zapier or Make
    • Technical but not DevOps → n8n Cloud or Pipedream
    • Full DevOps capability → n8n self-hosted or Airflow
  2. What’s your volume?

    • < 1,000/month → Anything works, pick easiest
    • 1,000–50,000/month → Make or n8n Cloud
    • 50,000+/month → n8n self-hosted
  3. Where must data live?

    • Anywhere → Cloud options are fine
    • Your infrastructure only → n8n or Airflow

Honest take: Most teams should start with Make or Zapier. Graduate to n8n when you hit limits—either cost, complexity, or control. Starting with n8n “because it’s free” often means workflows that never get finished.


Conclusion + Next Steps

You’ve read 5,000+ words about n8n. Now what?

Your Action Plan (This Week)

Day 1: Get it running

  • Cloud: Sign up free → build in browser
  • Self-hosted: docker run -p 5678:5678 n8nio/n8n → localhost:5678

Day 2-3: Build your first real workflow

  • Pick ONE repetitive task you do weekly
  • Build the workflow (webhook → logic → action)
  • Test with real data, not samples

Day 4-5: Make it production-ready

  • Set up Error Workflow (centralized alerting)
  • Enable Retry on Fail for API nodes
  • Add credentials properly (not hardcoded)

Week 2: Scale what works

  • Document your workflow (sticky notes)
  • Add monitoring (execution success rate)
  • Build workflow #2

Key Takeaways

  1. n8n = power + ownership. You trade simplicity for control. Worth it at scale.

  2. Start with Cloud. Graduate to self-hosted when you hit €100/month or need data control.

  3. Error handling isn’t optional. One Error Workflow catches everything. Set it up day one.

  4. The license is fine for 95% of users. Internal automation, agencies, startups—all good.

  5. Alternatives exist for a reason. Non-technical team? Start with Make or Zapier. Come back when you outgrow them.

Official Resources

Need Help?

Building complex automations? Migrating from another platform? Not sure where to start?

We build n8n workflows for businesses. From simple integrations to enterprise deployments.

Book a Free Audit →


This guide is updated regularly. Last update: January 2026. Found an error or have suggestions? Let us know.

FAQ

Frequently Asked Questions about n8n

Answers to the most common questions about n8n automation

01
Is n8n 'open source'?

n8n uses a 'Fair-code' / Sustainable Use License. It's free for self-hosting but has restrictions on reselling or hosting for others commercially.

02
Can I self-host for free?

Yes, n8n can be self-hosted completely free with full functionality. You only pay for your own infrastructure (server, database).

03
What's the difference between webhook and app trigger?

A webhook trigger waits for external HTTP calls to start a workflow. An app trigger polls or listens to a specific app (Gmail, Slack) for new events.

04
How to handle retries without duplicates?

Use idempotency keys, check if record exists before creating, or implement dead-letter queues for failed items that need manual review.

05
How to secure n8n exposed on Internet?

Use SSL/TLS, enable 2FA, configure reverse proxy with rate limiting, keep n8n updated, and restrict access via IP whitelist or VPN.

06
n8n Cloud vs self-host: which to choose?

Choose Cloud for speed and zero maintenance. Choose self-host for data control, internal network access, or strict compliance requirements.

Need Help with n8n?

Our experts can set up and optimize your n8n workflows

Free Audit