Jesse A. Green / notebook

n8n Administrator & Developer Guide

Generated May 2026 from n8n-io/n8n at c6534fa

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

n8n is a workflow automation platform built as a TypeScript monorepo. It provides a visual editor for designing automations, a server-side execution engine that runs workflows, and a growing suite of AI capabilities including an agent SDK, workflow builder, and instance-level AI assistant. The platform is designed for self-hosted deployment with support for horizontal scaling via queue-based worker distribution.

System Architecture

                          ┌─────────────────────────┐
                          │     Reverse Proxy        │
                          │   (nginx / Traefik)      │
                          └────────────┬────────────┘
                                       │
              ┌────────────────────────┼────────────────────────┐
              │                        │                        │
    ┌─────────▼──────────┐   ┌────────▼─────────┐   ┌─────────▼──────────┐
    │   Main Instance    │   │  Main Instance 2  │   │   Webhook Process  │
    │   (n8n start)      │   │  (HA / multi-main)│   │   (n8n webhook)    │
    │                    │   │                    │   │                    │
    │  ┌──────────────┐  │   └────────┬──────────┘   └────────┬──────────┘
    │  │ Express.js   │  │            │                        │
    │  │ HTTP Server  │  │            │                        │
    │  ├──────────────┤  │     ┌──────▼──────────────────────▼───────┐
    │  │ Editor UI    │  │     │            Redis (BullMQ)            │
    │  │ (Vue.js SPA) │  │     │  pub/sub + job queue + scaling svc   │
    │  ├──────────────┤  │     └──────┬──────────────────────┬───────┘
    │  │ REST API     │  │            │                      │
    │  ├──────────────┤  │     ┌──────▼──────┐        ┌──────▼──────┐
    │  │ Webhook      │  │     │  Worker 1   │        │  Worker N   │
    │  │ Handler      │  │     │ (n8n worker)│        │ (n8n worker)│
    │  ├──────────────┤  │     └──────┬──────┘        └──────┬──────┘
    │  │ Task Broker  │  │            │                      │
    │  │ (WS :5679)   │  │     ┌──────▼──────┐        ┌──────▼──────┐
    │  └──────────────┘  │     │ Task Runner │        │ Task Runner │
    │                    │     │ JS + Python  │        │ JS + Python  │
    └────────┬───────────┘     └─────────────┘        └─────────────┘
             │
    ┌────────▼───────────┐
    │    Database         │
    │  SQLite or Postgres │
    └────────────────────┘

Component Inventory

Component Path Role
packages/cli Server-side CLI + HTTP server Main entry point, Express.js server, CLI commands (start, worker, webhook, execute, audit)
packages/core Core engine library Credential encryption, binary data, expression engine, HTML sandboxing, HTTP proxy, error reporting
packages/workflow Workflow engine Node execution, expression evaluation, data routing, copy-on-write data management
packages/frontend/editor-ui Visual editor Vue.js 3 SPA with canvas-based workflow designer, Element Plus UI
packages/nodes-base Built-in nodes 400+ integration nodes (Google, Slack, HTTP, databases, etc.)
packages/@n8n/nodes-langchain AI/LangChain nodes LLM nodes, vector stores, memory, tools, agents
packages/@n8n/config Configuration system Decorator-based env var binding with Zod validation
packages/@n8n/db Database layer TypeORM fork, entities, migrations, role-based access control
packages/@n8n/di Dependency injection Lightweight singleton DI container (~145 lines)
packages/@n8n/task-runner JS task runner Sandboxed JavaScript Code node execution via WebSocket broker
packages/@n8n/task-runner-python Python task runner Sandboxed Python Code node execution with AST-level security
packages/@n8n/agents Agent SDK AI agent framework with tools, memory, guardrails, MCP, evals
packages/@n8n/instance-ai Instance AI Server-side AI assistant, workflow builder, multi-agent orchestration
packages/@n8n/ai-workflow-builder.ee AI Workflow Builder Licensed AI-powered workflow generation from natural language
packages/@n8n/chat-hub Chat Hub AI chat interface with artifact creation/editing
packages/@n8n/cli External CLI client oclif-based CLI for remote management of running n8n instances
packages/@n8n/client-oauth2 OAuth2 client OAuth2 code flow and credentials flow implementation
packages/@n8n/permissions Permissions RBAC scope and role definitions
packages/@n8n/errors Error types ApplicationError and IsolateError base classes
packages/@n8n/backend-common Backend commons CLI parser, license state management
packages/@n8n/api-types API type definitions Shared TypeScript types for REST API
packages/@n8n/constants Shared constants License features, instance types, LDAP config, password constraints
packages/@n8n/syslog-client Syslog client Syslog protocol implementation for log streaming
packages/@n8n/computer-use Computer use Browser automation agent (computer use tooling)
packages/@n8n/mcp-browser MCP browser Model Context Protocol browser discovery and integration
packages/@n8n/mcp-browser-extension MCP extension Browser extension for MCP server management
packages/@n8n/crdt CRDT Conflict-free replicated data types for collaborative editing
packages/@n8n/workflow-sdk Workflow SDK Programmatic workflow building, serialization, plugin system

Technology Stack

Layer Technology
Runtime Node.js >= 22.16
Language TypeScript 6.0.2, Python (task runner)
Build pnpm 10.32.1 (workspaces), Turborepo
Server Express.js
Frontend Vue.js 3.5+, Element Plus, PostHog (analytics)
Database SQLite (default) or PostgreSQL 16+ via TypeORM fork (@n8n/typeorm)
Queue BullMQ (Redis-backed) for scaling mode
Real-time WebSocket (push connections, task runner broker)
Auth JWT (HS256, cookie-based), LDAP, SAML, OIDC (licensed)
AI Vercel AI SDK v6+, LangChain, Mastra framework, MCP protocol
Testing Jest, Vitest, Playwright (E2E)
Code Quality Biome, Prettier, ESLint, Stylelint, Lefthook (pre-commit)
Coverage Codecov (component-level: backend, frontend, nodes, utils)

Note

The DI container (@n8n/di) is a custom minimal implementation using reflect-metadata — not NestJS or InversifyJS. It supports only singleton scope and uses concrete class constructors as service identifiers. Resolution works by recursively resolving constructor parameter types via TypeScript emit metadata.


2. System Requirements

Hardware Requirements

Deployment CPU RAM Disk
Single instance (SQLite) 1 core 2 GB 10 GB
Single instance (PostgreSQL) 2 cores 4 GB 20 GB
Queue mode (per worker) 2 cores 4 GB 10 GB
Multi-main HA 2 cores per main 4 GB per main 20 GB
Task runner (per runner) 1 core 1 GB 5 GB

Software Requirements

Requirement Version
Node.js >= 22.16
pnpm (source builds) >= 10.22.0
PostgreSQL (production) 16+ recommended
Redis (queue mode) 6.2+
Docker (containerized) 20.10+
Docker Compose v2+

Network Requirements

Port Service Notes
5678 n8n HTTP server Main UI, API, webhooks
5679 Task broker WebSocket Internal: runners connect here
5681 JS task runner health check Internal only
5682 Python task runner health check Internal only

3. Configuration Reference

Configuration Architecture

n8n uses a decorator-based configuration system (@Config, @Env(), @Nested) that binds environment variables to typed TypeScript classes with Zod schema validation. The root configuration is GlobalConfig, which aggregates all nested config sections.

Key design features:

  • All env vars support _FILE suffix to read from file (Docker secrets)
  • Zod schemas validate values at startup
  • Type coercion handles Number, Boolean, Date, String, and custom types (CommaSeparatedStringArray, ColonSeparatedStringArray)
  • A sanitize() method on config classes runs after construction for post-validation logic

Core Server Configuration

Variable Type Default Description
N8N_HOST string localhost Server hostname
N8N_PORT number 5678 HTTP port
N8N_LISTEN_ADDRESS string :: IP address to bind to
N8N_PROTOCOL string http Protocol (http or https)
N8N_PATH string / Base path (for subpath hosting)
N8N_SSL_KEY string '' SSL private key file path
N8N_SSL_CERT string '' SSL certificate file path
N8N_PROXY_HOPS number 0 Reverse proxy hop count for trust proxy
N8N_EDITOR_BASE_URL string '' Public URL for editor and emails
N8N_DEFAULT_LOCALE string en Default UI locale
N8N_HIDE_USAGE_PAGE boolean false Hide the usage page
N8N_CANVAS_ONLY boolean false Canvas-only mode
N8N_USER_FOLDER string $HOME Home directory for .n8n folder
GENERIC_TIMEZONE string America/New_York Default timezone
N8N_GRACEFUL_SHUTDOWN_TIMEOUT number — Graceful shutdown timeout (seconds)

Database Configuration

Variable Type Default Description
DB_TYPE string sqlite sqlite or postgresdb
DB_POSTGRESDB_HOST string — PostgreSQL hostname
DB_POSTGRESDB_PASSWORD string — PostgreSQL password
DB_SQLITE_POOL_SIZE number — SQLite connection pool size

Important

SQLite uses WAL mode automatically. For queue mode (multi-worker), PostgreSQL is required — SQLite does not support concurrent access from multiple processes.

Execution Configuration

Variable Type Default Description
EXECUTIONS_MODE string regular Execution mode: regular (in-process) or queue (Redis-backed)
N8N_CONCURRENCY_PRODUCTION_LIMIT number — Max concurrent production executions per worker

Queue / Scaling Configuration

Variable Type Default Description
QUEUE_BULL_REDIS_HOST string — Redis host for BullMQ
QUEUE_HEALTH_CHECK_ACTIVE boolean false Enable queue health checks on workers
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS boolean — Route manual executions to queue workers
N8N_MULTI_MAIN_SETUP_ENABLED boolean false Enable multi-main HA mode

Task Runner Configuration

Variable Type Default Description
N8N_RUNNERS_MODE string — Runner mode (external for container-based runners)
N8N_RUNNERS_AUTH_TOKEN string — Auth token for runner ↔ broker communication
N8N_RUNNERS_TASK_BROKER_URI string http://127.0.0.1:5679 Broker URI runners connect to
N8N_RUNNERS_GRANT_TOKEN string — Grant token for runner auth
N8N_RUNNERS_MAX_PAYLOAD number 1073741824 Max payload size (bytes, default 1 GiB)
N8N_RUNNERS_MAX_CONCURRENCY number 10 Max concurrent tasks per runner
N8N_RUNNERS_TASK_TIMEOUT number 300 Task timeout (seconds)
N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT number 0 Idle shutdown timeout (0 = disabled)
N8N_RUNNERS_HEALTH_CHECK_SERVER_ENABLED boolean false Enable runner health check
N8N_RUNNERS_HEALTH_CHECK_SERVER_HOST string 127.0.0.1 Health check listen address
N8N_RUNNERS_HEALTH_CHECK_SERVER_PORT number 5681 Health check port (JS runner)
N8N_RUNNERS_INSECURE_MODE boolean false Disable JS runner sandboxing
NODE_FUNCTION_ALLOW_BUILTIN string '' Allowed Node.js built-in modules
NODE_FUNCTION_ALLOW_EXTERNAL string '' Allowed external npm modules
N8N_RUNNERS_STDLIB_ALLOW string '' Allowed Python stdlib modules
N8N_RUNNERS_EXTERNAL_ALLOW string '' Allowed Python external packages

Warning

Setting N8N_RUNNERS_INSECURE_MODE=true disables the JavaScript sandbox entirely. This should only be used in trusted environments. The Python runner does not have an insecure mode — its AST-level security analysis is always active.

Authentication & Security Configuration

Variable Type Default Description
N8N_ENCRYPTION_KEY string auto-generated Credential encryption key. Share across all instances
N8N_PREVIEW_MODE boolean — Allow unauthenticated access on specific endpoints
N8N_BLOCK_ENV_ACCESS_IN_NODE boolean — Block env access in Code nodes
N8N_SKIP_AUTH_ON_OAUTH_CALLBACK boolean — Skip auth on OAuth callback endpoints

Proxy Configuration

Variable Type Description
HTTP_PROXY string HTTP proxy URL
HTTPS_PROXY string HTTPS proxy URL
ALL_PROXY string Proxy for all protocols
NO_PROXY string Comma-separated bypass list

Observability Configuration

Variable Type Default Description
N8N_METRICS boolean false Enable Prometheus metrics endpoint
N8N_DIAGNOSTICS_ENABLED boolean true Enable telemetry/diagnostics
N8N_LOG_LEVEL string — Log level (error, warn, info, debug, silent)
N8N_SENTRY_DSN string '' Sentry DSN for error tracking
N8N_SENTRY_TRACES_SAMPLE_RATE number 0 Sentry traces sample rate (0.0–1.0)
N8N_SENTRY_PROFILES_SAMPLE_RATE number 0 Sentry profiling sample rate (0.0–1.0)
ENABLE_OBSERVABILITY boolean — Enable OpenTelemetry observability

AI Configuration

Variable Type Description
N8N_AI_ENABLED boolean Enable AI features globally
N8N_AI_ANTHROPIC_KEY string Anthropic API key for AI workflow builder
N8N_INSTANCE_AI_MODEL_API_KEY string API key for Instance AI model

License Configuration

Variable Type Description
N8N_LICENSE_ACTIVATION_KEY string License activation key
N8N_LICENSE_CERT string License certificate
N8N_LICENSE_TENANT_ID string License tenant ID

Storage Configuration

Variable Type Default Description
N8N_STORAGE_PATH string — Override default storage path
N8N_BINARY_DATA_STORAGE_PATH string — Binary data storage path
N8N_MIGRATE_FS_STORAGE_PATH string — Migration source for filesystem storage

Config Files

File Format Location Purpose
GlobalConfig TypeScript classes packages/@n8n/config/src/ Primary config system (env var decorators)
Legacy schema TypeScript packages/cli/src/config/schema.ts Deprecated legacy config (new vars go to @n8n/config)

Note

The legacy config schema at packages/cli/src/config/schema.ts is deprecated. All new configuration should be added to packages/@n8n/config/src/ using @Env() decorators. The legacy schema remains for backward compatibility.


4. Deployment & Scaling

Deployment Modes

n8n supports three deployment architectures:

Single Instance (Regular Mode)

The simplest deployment — a single n8n process handles the UI, API, webhook processing, and workflow execution.

services:
  n8n:
    image: ghcr.io/n8n-io/n8n
    ports:
      - "5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    environment:
      - DB_TYPE=sqlite
      - DB_SQLITE_POOL_SIZE=3
volumes:
  n8n_data:

Tip

Single instance with SQLite is sufficient for personal use and small teams (< 10 concurrent workflows).

Queue Mode (Single Main + Workers)

Separates the UI/API from workflow execution. The main instance enqueues jobs to Redis; workers pull and execute them.

services:
  postgres:
    image: postgres:16.4
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:6.2.14-alpine

  n8n:
    image: ghcr.io/n8n-io/n8n
    ports:
      - "5678:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PASSWORD=password
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_METRICS=true
    depends_on:
      - postgres
      - redis

  worker:
    image: ghcr.io/n8n-io/n8n
    command: worker
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PASSWORD=password
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_HEALTH_CHECK_ACTIVE=true
      - N8N_CONCURRENCY_PRODUCTION_LIMIT=10
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    depends_on:
      - n8n

  task-runners:
    image: ghcr.io/n8n-io/n8n-task-runners
    environment:
      - N8N_RUNNERS_TASK_BROKER_URI=http://worker:5679
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
    depends_on:
      - worker

volumes:
  postgres_data:

Important

All instances in queue mode must share the same N8N_ENCRYPTION_KEY, database, and Redis. The first worker to start runs database migrations; subsequent workers wait for it to be healthy.

Multi-Main HA (High Availability)

Multiple main instances behind a load balancer, with Redis-based leader election and pub/sub coordination.

services:
  postgres:
    image: postgres:16.4
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

  redis:
    image: redis:6.2.14-alpine

  n8n-main-1:
    image: ghcr.io/n8n-io/n8n
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PASSWORD=password
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - N8N_MULTI_MAIN_SETUP_ENABLED=true
      - N8N_PROXY_HOPS=1
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_LICENSE_CERT=${N8N_LICENSE_CERT}

  n8n-main-2:
    image: ghcr.io/n8n-io/n8n
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PASSWORD=password
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - N8N_MULTI_MAIN_SETUP_ENABLED=true
      - N8N_PROXY_HOPS=1
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_LICENSE_CERT=${N8N_LICENSE_CERT}

  nginx:
    image: nginx:alpine
    ports:
      - "5678:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - n8n-main-1
      - n8n-main-2

Multi-main uses a leader/follower pattern:

  • Leader — handles workflow activations, cron scheduling, and event bus
  • Follower — serves the UI and API, routes executions to queue
  • Leader election via Redis with exponential backoff for follower license sync

Important

Multi-main requires an Enterprise license. Instance roles (leader, follower) are managed automatically via Redis. All main instances must share N8N_ENCRYPTION_KEY, N8N_LICENSE_CERT, and N8N_LICENSE_ACTIVATION_KEY.

Health Check Endpoints

Endpoint Auth Response Description
GET /healthz None {"status":"ok"} Basic liveness (always returns 200)
GET /healthz/readiness None {"status":"ok"} or 503 Readiness probe: checks DB connection, migration status, and full initialization

Task Runner Deployment

Task runners execute Code node JavaScript and Python in isolated processes. In external mode, they run as separate containers communicating with the broker via WebSocket.

Runner configuration file (n8n-task-runners.json):

{
  "task-runners": [
    {
      "runner-type": "javascript",
      "name": "JavaScript Task Runner",
      "command": "/usr/local/bin/node",
      "args": ["--disallow-code-generation-from-strings", "--disable-proto=delete", "/opt/runners/task-runner-javascript/dist/start.js"],
      "health-check-port": 5681,
      "allowed-env": ["PATH", "GENERIC_TIMEZONE", "NODE_OPTIONS"]
    },
    {
      "runner-type": "python",
      "name": "Python Task Runner",
      "command": "/opt/runners/task-runner-python/.venv/bin/python",
      "args": ["-I", "-B", "-X", "disable_remote_debug", "-m", "src.main"],
      "health-check-port": 5682
    }
  ]
}

Runner authentication flow:

  1. Runner authenticates with the broker using N8N_RUNNERS_AUTH_TOKEN to obtain a grant token
  2. Grant tokens are 32-byte random hex, cached with 15-second TTL, single-use
  3. Runner upgrades to WebSocket using the grant token as a Bearer token
  4. Token validation uses timing-safe comparison

5. Operations

CLI Commands (Server-Side)

Command Description Key Flags
n8n start Start main instance (UI + API + execution) --open / -o (auto-open browser)
n8n worker Start queue worker --concurrency=N (default 10)
n8n webhook Start dedicated webhook process Requires EXECUTIONS_MODE=queue
n8n execute Execute a single workflow --id=N, --rawOutput
n8n execute-batch Batch execute workflows --ids, --concurrency, --snapshot, --compare, --retries
n8n audit Security audit --categories (comma-separated risk categories)

Note

The n8n worker command requires EXECUTIONS_MODE=queue and will warn if concurrency is set below 5. Workers set up Redis-based scaling, pub/sub orchestration, and the event bus. The n8n webhook command creates a dedicated process that only handles production webhook URLs.

External CLI Commands (@n8n/cli)

The external CLI connects to a running n8n instance via the REST API:

Command Description
login / logout Authenticate with an n8n instance
config:set-url / config:set-api-key / config:show Manage connection configuration
workflow:list / get / create / update / delete Workflow management
workflow:activate / deactivate / tags / transfer Workflow operations
execution:list / get / retry / stop / delete Execution management
credential:list / get / schema / create / delete / transfer Credential management
tag:list / create / update / delete Tag management
project:list / get / create / update / delete / members Project management
variable:list / create / update / delete Variable management
data-table:list / get / create / delete / rows / add-rows Data table management
user:list / get User listing
source-control:pull Pull source control changes
skill:install Install community skills
audit Run security audit

CLI global flags: --url, --apiKey, --format (table/json/id-only), --json, --quiet, --noHeader, --jq, --debug

Configuration resolution: CLI flags > env vars (N8N_URL, N8N_API_KEY) > config file (~/.n8n-cli/config.json)

Startup Sequence

The n8n start command executes the following sequence:

  1. Initialize database connection (PostgreSQL or SQLite with WAL mode)
  2. Run pending database migrations
  3. Set up Sentry error reporting (if configured)
  4. Initialize license subsystem (N8N_LICENSE_ACTIVATION_KEY)
  5. Start expression engine (configurable pool size and bridge settings)
  6. Initialize binary data service (S3 if licensed: feat:binaryDataS3)
  7. Load community packages (if enabled)
  8. Start task runners (if configured)
  9. Build Express.js server with middleware stack
  10. Register webhook routes (live, test, waiting, forms, MCP)
  11. Generate static assets with injected configuration
  12. Activate workflows and start cron schedules
  13. Enable execution pruning and workflow history compaction
  14. Re-queue executions that were in-progress during prior shutdown

Monitoring Checklist

  • [ ] Health endpoint responsive: GET /healthz
  • [ ] Readiness probe passing: GET /healthz/readiness
  • [ ] Worker queue health (if queue mode): QUEUE_HEALTH_CHECK_ACTIVE=true
  • [ ] Task runner health checks (if external): ports 5681 (JS) and 5682 (Python)
  • [ ] Prometheus metrics (if enabled): N8N_METRICS=true
  • [ ] Execution log retention configured
  • [ ] Database disk usage monitored
  • [ ] Redis memory usage monitored (queue mode)

Tip

In queue mode, use the worker concurrency limit (N8N_CONCURRENCY_PRODUCTION_LIMIT) to prevent resource exhaustion. Start with 10 and adjust based on workflow complexity and available resources.

Backup Strategy

Component Backup Method
SQLite database Copy ~/.n8n/database.sqlite (stop n8n first or use SQLite backup API)
PostgreSQL database pg_dump
Encryption key N8N_ENCRYPTION_KEY — critical, without it credentials are unrecoverable
Workflows Export via UI or CLI (workflow:list --format=json)
Credentials Stored encrypted in DB — backed up with database
Binary data Back up N8N_BINARY_DATA_STORAGE_PATH or S3 bucket

Caution

The N8N_ENCRYPTION_KEY is the most critical backup item. If lost, all stored credentials become permanently unreadable. Store it securely in a secrets manager, not in plain text alongside backups.


6. Performance

Expression Engine Configuration

Variable Description
Expression pool size Configurable via expressionEngine config section
Bridge timeout Controls expression evaluation timeout
Bridge memory Controls memory limit for expression evaluation
Code cache Caches compiled expression code

Concurrency Tuning

  • Production concurrency: N8N_CONCURRENCY_PRODUCTION_LIMIT controls max concurrent workflow executions per worker
  • Task runner concurrency: N8N_RUNNERS_MAX_CONCURRENCY controls max concurrent Code node tasks per runner (default 10)
  • Worker count: Scale horizontally by adding more n8n worker containers
  • Task runner timeout: N8N_RUNNERS_TASK_TIMEOUT (default 300s / 5 min)

Database Optimization

  • SQLite: DB_SQLITE_POOL_SIZE tunes connection pooling; VACUUM runs on startup
  • PostgreSQL: Use connection pooling (PgBouncer) for high-concurrency deployments
  • Execution pruning: Configure to automatically clean old execution data
  • Workflow history compaction: Runs on startup to reduce storage

7. Security

Authentication Architecture

n8n supports multiple authentication mechanisms:

JWT Cookie Authentication (default):

  • Algorithm: HS256
  • Payload: user ID, password hash, browser ID (anti-hijacking), MFA status
  • Cookie: httpOnly: true, configurable sameSite and secure
  • Auto-refresh when within 25% of expiration
  • Revoked tokens tracked in InvalidAuthTokenRepository

Browser ID anti-hijacking:

  • Each session is bound to a browser ID (hashed in JWT)
  • Validation is skipped on endpoints where custom headers cannot be sent: WebSocket push, binary-data downloads, OAuth callbacks, type files, chat hub attachments, Instance AI SSE (EventSource limitation)

Auth handler registry:

  • Pluggable via @AuthHandler() decorator
  • Default: email handler (password-based with bcrypt)
  • LDAP: Licensed feature, detects former LDAP users and suggests password reset
  • SAML: Licensed Enterprise feature, middleware checks isSamlLicensed() and isSamlLicensedAndEnabled()
  • OIDC: Licensed feature

MFA enforcement:

  • When MFA is enforced globally, users without MFA get a mfaRequired: true response
  • JWT tracks whether MFA was used during authentication (usedMfa field)

Password constraints:

  • Minimum 8 characters, maximum 64 characters

Warning

LDAP email uniqueness is enforced to prevent privilege escalation via email-based account linking. If LDAP login is disabled, former LDAP users are informed to reset their password.

Task Runner Sandboxing

JavaScript runner security:

  • V8 flags: --disallow-code-generation-from-strings, --disable-proto=delete
  • Module allowlists: NODE_FUNCTION_ALLOW_BUILTIN, NODE_FUNCTION_ALLOW_EXTERNAL
  • Default allowed: crypto (builtin), moment (external)
  • Strict env var allowlist — only specified vars passed to runner process

Python runner security (AST-level):

  • Python flags: -I (isolated), -B (no bytecode), -X disable_remote_debug
  • Blocked builtins: eval, exec, compile, open, input, breakpoint, getattr, setattr, delattr, hasattr, dir, memoryview, __build_class__, globals, locals, vars, type, object
  • Blocked attributes: __subclasses__, __globals__, __builtins__, __traceback__, f_back, f_globals, f_code, gi_frame, cr_frame, __base__, __class__, __mro__, __dict__, __import__
  • Blocked names: __loader__, __builtins__, __globals__, __spec__, __name__
  • Import validation: allowlist-based, relative imports blocked, dynamic __import__() blocked
  • Name-mangled attributes (_ClassName__attr) blocked
  • String pattern scanning for dangerous attribute access
  • Default: both N8N_RUNNERS_STDLIB_ALLOW and N8N_RUNNERS_EXTERNAL_ALLOW are empty (all imports blocked)

Caution

The Python runner's security model is defense-in-depth: AST analysis (blocked builtins, attributes, names), import validation (allowlists), string scanning (pattern detection), and subprocess isolation. Relaxing any of these (e.g., adding os to N8N_RUNNERS_STDLIB_ALLOW) significantly increases the attack surface.

HTML Sandboxing

Webhook and form HTML responses are sandboxed with CSP headers. Controlled by:

  • SecurityConfig.disableWebhookHtmlSandboxing
  • SecurityConfig.disableFormHtmlSandboxing

SSRF Protection

Built-in SSRF protection blocks requests to private IP ranges. Configurable via SsrfProtectionConfig.

Credential Encryption

All credentials are encrypted at rest using the Cipher service, keyed by N8N_ENCRYPTION_KEY. The Credentials class supports setData, getData, updateData, getDataToSave. Error types: NO_DATA, DECRYPTION_FAILED, INVALID_JSON, INVALID_DATA.

Security Scanning

  • Trivy scanning with VEX-based false positive triage (security/vex.openvex.json)
  • Custom Rego ignore policy (security/trivy-ignore-policy.rego)
  • Cubic AI code review with security-focused rules

Licensed Security Features

Feature License Flag Description
LDAP feat:ldap LDAP authentication
SAML feat:saml SAML SSO
OIDC feat:oidc OpenID Connect SSO
MFA enforcement feat:mfaEnforcement Enforce MFA for all users
Log streaming feat:logStreaming Stream logs to external destinations
External secrets feat:externalSecrets External secret management
Source control feat:sourceControl Git-based workflow versioning
Data redaction feat:dataRedaction Redact sensitive data in logs
Advanced permissions feat:advancedPermissions Granular RBAC
Custom roles feat:customRoles Define custom permission roles

8. Developer Internals

Repository Structure

n8n/
├── packages/
│   ├── cli/                         Server-side CLI + HTTP server
│   │   ├── src/
│   │   │   ├── commands/            CLI commands (start, worker, webhook, execute, audit)
│   │   │   ├── controllers/         REST API controllers (33 files)
│   │   │   ├── services/            Business logic services (40 files)
│   │   │   ├── auth/                Auth service, handlers, handler registry
│   │   │   ├── config/              Legacy config schema
│   │   │   ├── errors/              Error types (28 files)
│   │   │   ├── modules/             Feature modules
│   │   │   │   ├── source-control.ee/  Source control (licensed)
│   │   │   │   ├── sso-saml/        SAML SSO (licensed)
│   │   │   │   ├── dynamic-credentials.ee/  Dynamic credentials (licensed)
│   │   │   │   ├── token-exchange/  Token exchange
│   │   │   │   ├── data-table/      Data table operations
│   │   │   │   ├── quick-connect/   Quick connect handlers
│   │   │   │   ├── otel/            OpenTelemetry handlers
│   │   │   │   └── mcp/             MCP integration
│   │   │   ├── task-runners/        Task broker, auth, errors
│   │   │   ├── public-api/          Public API v1 handlers
│   │   │   └── utils/               Utility functions
│   │   └── test/                    Integration + unit tests
│   ├── core/                        Core engine
│   │   └── src/
│   │       ├── credentials.ts       Credential encryption/decryption
│   │       ├── storage.config.ts    Storage path configuration
│   │       ├── http-proxy.ts        HTTP proxy support
│   │       ├── errors/              Error types (12 files)
│   │       ├── utils/               Assertions, helpers
│   │       └── execution-engine/    Node execution context
│   ├── workflow/                    Workflow engine
│   │   └── src/
│   │       ├── expression.ts        Expression evaluation
│   │       ├── augmentObject.ts     Copy-on-write data proxying
│   │       ├── common/              Shared utilities
│   │       └── errors/              22 error types
│   ├── nodes-base/                  Built-in integration nodes (400+)
│   │   ├── nodes/                   Node implementations
│   │   ├── credentials/             Credential types
│   │   └── utils/                   Shared node utilities
│   ├── frontend/
│   │   ├── editor-ui/               Vue.js 3 workflow editor SPA
│   │   │   └── src/
│   │   │       ├── app/             Application shell, stores, composables
│   │   │       └── features/        Feature modules (workflows, settings, AI, NDV)
│   │   └── @n8n/
│   │       ├── design-system/       Shared UI component library
│   │       ├── chat/                Chat widget
│   │       ├── composables/         Shared Vue composables
│   │       ├── i18n/                Internationalization
│   │       ├── rest-api-client/     REST API client
│   │       └── stores/              Shared Pinia stores
│   ├── node-dev/                    Community node development CLI
│   ├── extensions/
│   │   └── insights/                Analytics/insights module
│   ├── testing/
│   │   ├── playwright/              E2E tests
│   │   ├── containers/              Docker test containers
│   │   ├── janitor/                 Code health tooling
│   │   ├── rules-engine/            Test rule engine
│   │   └── code-health/             Code quality checks
│   └── @n8n/
│       ├── config/                  Configuration system (@Env decorators)
│       ├── db/                      Database layer (TypeORM, migrations)
│       ├── di/                      Dependency injection container
│       ├── errors/                  Base error types
│       ├── constants/               Shared constants, license features
│       ├── permissions/             RBAC definitions
│       ├── api-types/               API type definitions
│       ├── backend-common/          CLI parser, license state
│       ├── agents/                  AI Agent SDK
│       ├── instance-ai/             Instance-level AI assistant
│       ├── ai-workflow-builder.ee/  AI workflow builder (licensed)
│       ├── ai-utilities/            AI utility functions
│       ├── ai-node-sdk/             SDK for building AI nodes
│       ├── chat-hub/                Chat hub with artifacts
│       ├── task-runner/             JS task runner
│       ├── task-runner-python/      Python task runner
│       ├── cli/                     External CLI client (oclif)
│       ├── client-oauth2/           OAuth2 client
│       ├── nodes-langchain/         LangChain integration nodes
│       ├── workflow-sdk/            Programmatic workflow SDK
│       ├── computer-use/            Computer use agent
│       ├── mcp-browser/             MCP browser discovery
│       ├── mcp-browser-extension/   MCP browser extension
│       ├── crdt/                    CRDT for collaborative editing
│       ├── syslog-client/           Syslog protocol client
│       ├── codemirror-lang/         CodeMirror language support
│       ├── codemirror-lang-sql/     SQL language for CodeMirror
│       ├── codemirror-lang-html/    HTML language for CodeMirror
│       ├── expression-runtime/      Expression runtime engine
│       ├── imap/                    IMAP client
│       ├── json-schema-to-zod/      JSON Schema to Zod converter
│       ├── benchmark/               Benchmark tooling
│       ├── extension-sdk/           Extension SDK
│       ├── local-gateway/           Local gateway
│       ├── node-cli/                Node CLI tools + templates
│       ├── eslint-config/           ESLint configuration
│       ├── eslint-plugin-community-nodes/  ESLint plugin
│       ├── stylelint-config/        Stylelint configuration
│       ├── backend-test-utils/      Backend test utilities
│       ├── typescript-config/       Shared TypeScript config
│       └── utils/                   Shared utility functions
├── docker/
│   └── images/
│       ├── n8n/                     Main Docker image entrypoint
│       ├── n8n-base/                Base Docker image
│       └── runners/                 Task runner Docker image + config
├── security/
│   ├── trivy.yaml                   Trivy scan config
│   └── vex.openvex.json             VEX false positive triage
├── scripts/                         Build, deploy, utility scripts
├── patches/                         pnpm dependency patches
└── pnpm-workspace.yaml              Workspace definition

Architecture Deep Dive

Data flow for workflow execution:

  1. User triggers execution (manual, webhook, schedule, or external trigger)
  2. Main instance builds execution context (node types, credentials, input data)
  3. In queue mode: execution is enqueued to Redis via BullMQ; a worker dequeues it
  4. Workflow engine traverses the node graph left-to-right, depth-first
  5. Each node receives input items, processes them, and produces output items
  6. Data passes between nodes via a copy-on-write proxy system (augmentObject / augmentArray) using ES6 Proxy for memory-efficient lazy cloning
  7. Code nodes (JavaScript/Python) are delegated to task runners via WebSocket broker
  8. Results are stored in the database; binary data stored at configured path (filesystem or S3)

Task runner broker protocol:

The broker mediates between runners and requesters using a WebSocket-based message protocol:

Direction Message Types
Broker → Runner InfoRequest, RunnerRegistered, TaskOfferAccept, TaskCancel, TaskSettings, RPCResponse, TaskDataResponse, NodeTypes, Drain
Broker → Requester TaskReady, TaskDone, TaskError, RequestExpired, TaskDataRequest, NodeTypesRequest, RPC
Runner → Broker Info, TaskAccepted, TaskRejected, TaskDeferred, TaskDone, TaskError, TaskOffer, TaskDataRequest, NodeTypesRequest, RPC
Requester → Broker TaskSettings, TaskCancel, TaskDataResponse, NodeTypesResponse, RPCResponse, TaskRequest

Runners use a pull-based offer model: they proactively send TaskOffer messages with a validity window. The broker matches offers to pending requests. TaskDeferred allows the launcher to hold a task until the runner is ready.

Frontend architecture:

The editor UI is a Vue.js 3 SPA with:

  • Canvas-based workflow designer with INodeUi extending INode with position ([x, y]), color, notes
  • Element Plus component library
  • Pinia state management
  • PostHog integration for feature flags and session recording
  • RBAC-aware: ProjectSharingData and Scope from @n8n/permissions
  • Real-time updates via WebSocket push connections

Module Reference

Core Packages

@n8n/di — Dependency injection container (~145 lines)

  • @Service() decorator marks classes as injectable with optional factory functions
  • Container.get(type) resolves singletons recursively via constructor parameter metadata
  • Circular dependency detection via resolution stack
  • Container.set(type, instance) for manual registration
  • Container.reset() clears instances but preserves registrations (for testing)

@n8n/config — Configuration system

  • @Config class decorator — auto-reads environment variables at construction
  • @Env(envName) property decorator — binds a property to an env var
  • @Nested property decorator — creates nested config hierarchy
  • Zod schema validation on values
  • _FILE suffix support for Docker secrets

@n8n/db — Database layer

  • TypeORM fork (@n8n/typeorm) supporting SQLite and PostgreSQL
  • Entity mixins: WithStringId, WithTimestamps, WithTimestampsAndStringId
  • Column helpers: JsonColumn, DateTimeColumn
  • Transaction support: withTransaction helper
  • Custom validators: NoXss, NoUrl
  • Migration DSL: CreateTable, Column
  • Advisory locking: DbLockService with DbLock enum (PostgreSQL native, SQLite fallback)
  • Role-based access control: AuthRolesService syncs roles/scopes from code to database at startup

@n8n/permissions — RBAC definitions

  • Global roles: owner, admin, member, chatUser
  • Project roles: personalOwner, admin, editor, viewer, chatUser
  • Scopes define granular permissions per resource type

@n8n/errors — Error hierarchy

  • ApplicationError — base error class
  • IsolateError — error from sandboxed execution

@n8n/constants — Shared constants

  • 30+ licensed feature flags (SHARING, LDAP, SAML, OIDC, AI_GATEWAY, FOLDERS, etc.)
  • License quotas: activeWorkflows, maxVariables, users, aiCredits, etc.
  • Instance types: main, webhook, worker
  • Instance roles: unset, leader, follower

AI Packages

@n8n/agents — AI Agent SDK

  • Agent builder: tools, memory, guardrails, model configuration
  • Tool with ToolContext and InterruptibleToolContext
  • Memory: SqliteMemory, PostgresMemory backends with semantic recall
  • Guardrail: PII detection, content safety
  • Eval / evaluate: evaluation framework with built-in evals (correctness, helpfulness, string similarity, categorization, keyword containment, JSON validity, tool call accuracy)
  • McpClient: Model Context Protocol client
  • Workspace: BaseFilesystem, BaseSandbox, SandboxProcessManager for sandboxed execution
  • Provider support: OpenAI, Anthropic, Google, xAI with provider-specific thinking configs
  • Code generation: generateAgentCode from schema definitions

@n8n/instance-ai — Instance-level AI

  • Built on Mastra framework with AI SDK v5
  • Multi-agent orchestration: workflow builder, data table agent, research agent, delegate tasks
  • Workflow loop system: WorkflowTaskCoordinator, WorkflowLoopRuntime for build-verify-iterate
  • Planned tasks: PlannedTaskCoordinator for scheduled AI tasks
  • Background task management: BackgroundTaskManager
  • Resumable streaming: SSE-based with suspend/resume
  • LangSmith tracing integration
  • MCP client management
  • Workspace sandboxing: BuilderSandboxFactory, SnapshotManager

@n8n/ai-workflow-builder.ee — AI Workflow Builder (Enterprise)

  • Licensed feature (feat:aiBuilder)
  • Generates workflows from natural language descriptions
  • Streaming JSON-lines responses
  • Workflow context awareness (current workflow, execution data, schema)
  • Validation utilities for generated workflows

@n8n/chat-hub — Chat artifact system

  • collectChatArtifacts() processes chat messages into documents
  • Artifact types: artifact-create, artifact-edit
  • Supports markdown and HTML artifacts
  • String replacement editing with replaceAll mode

@n8n/ai-node-sdk — SDK for community AI nodes

  • supplyModel / supplyMemory — supply AI models and memory to the n8n runtime
  • BaseChatModel / BaseChatHistory / BaseChatMemory — abstract base classes
  • WindowedChatMemory — sliding window memory implementation

Code Patterns and Conventions

Pattern Usage
Dependency injection @Service() + constructor injection via @n8n/di
Configuration @Config + @Env() + @Nested decorators
Error hierarchy ApplicationError → domain-specific errors
REST controllers Express.js route handlers in packages/cli/src/controllers/
Feature modules packages/cli/src/modules/ with .ee suffix for licensed features
Copy-on-write data ES6 Proxy-based lazy cloning (augmentObject, augmentArray)
Entity IDs NanoID generation via generateNanoId
Database locking Advisory locks via DbLockService for safe multi-instance operations
Test isolation Container.reset() clears DI singletons between tests

Testing Strategy

Type Framework Location Description
Unit Jest / Vitest *.test.ts co-located Component-level tests
Integration Jest + Supertest packages/cli/test/integration/ API + database tests
E2E Playwright packages/testing/playwright/ Full browser-based tests
Benchmark k6 packages/@n8n/benchmark/ Performance benchmarks
Code health Custom rules engine packages/testing/janitor/ Static analysis, method usage tracking

Code coverage tracked via Codecov with component-level targets: backend, frontend, nodes, utils.

Contributing

The repository uses:

  • pnpm workspaces with pnpm-workspace.yaml defining packages in packages/*, packages/@n8n/*, packages/frontend/**, packages/extensions/**, packages/testing/**
  • Turborepo for task orchestration (build, typecheck, lint, test, dev, watch)
  • Strict catalog mode in pnpm with minimum release age of 4320 (3 days)
  • Lefthook pre-commit hooks: Biome, Prettier, Stylelint, actionlint, workspace-deps check
  • Prettier formatting: tabs, single quotes, trailing commas
  • Biome for JavaScript/TypeScript/JSON linting
  • TypeScript 6.0.2 across all packages

Development commands:

# Full development mode (backend + frontend)
pnpm dev

# Backend only
pnpm dev:be

# Frontend editor only
pnpm dev:fe

# AI nodes development
pnpm dev:ai

# E2E tests
pnpm dev:e2e

# Run all tests
pnpm test

# Lint
pnpm lint
pnpm format:check

# Build
pnpm build

9. Integration Points

REST API (Public)

n8n exposes a public REST API at /api/v1/ authenticated via X-N8N-API-KEY header:

Method Path Description
GET /api/v1/workflows List workflows
POST /api/v1/workflows Create workflow
GET /api/v1/workflows/:id Get workflow
PUT /api/v1/workflows/:id Update workflow
DELETE /api/v1/workflows/:id Delete workflow
POST /api/v1/workflows/:id/activate Activate workflow
POST /api/v1/workflows/:id/deactivate Deactivate workflow
GET /api/v1/executions List executions
GET /api/v1/executions/:id Get execution
POST /api/v1/executions/:id/retry Retry execution
DELETE /api/v1/executions/:id Delete execution
GET /api/v1/credentials List credentials
GET /api/v1/credentials/schema/:type Get credential schema
POST /api/v1/credentials Create credential
GET /api/v1/tags List tags
POST /api/v1/tags Create tag
GET /api/v1/users List users

Internal REST API

Controllers in packages/cli/src/controllers/ expose additional endpoints:

Controller Path Notable Endpoints
ActiveWorkflowsController /active-workflows GET / (list active IDs), GET /error/:id (activation errors)
AiController /ai POST /build (AI workflow builder), POST /chat (AI assistant), POST /ask-ai, POST /free-credits, GET /gateway/config

Webhook Integration

Path Pattern Type Auth
/webhook/:path Production webhook None (public)
/webhook-test/:path Test webhook (editor open only) Session cookie
/webhook-waiting/:path Waiting webhook (Wait node) None
/form/:path Form trigger None
/form-waiting/:path Waiting form None
/mcp/:path MCP server endpoint None

Event Bus / Log Streaming

The MessageEventBus system supports streaming events to external destinations with a circuit breaker pattern for resilience. This is a licensed feature (feat:logStreaming).

Source Control

Git-based workflow versioning is available as a licensed feature (feat:sourceControl). Managed via packages/cli/src/modules/source-control.ee/.


Troubleshooting

Error: DbConnectionTimeoutError

Cause: Database connection pool exhausted or database server unreachable.

Solution:

  1. Check database server is running and accessible
  2. Increase connection pool size for PostgreSQL
  3. For SQLite, increase DB_SQLITE_POOL_SIZE

Prevention: Monitor database connections; use PostgreSQL for production workloads.

Error: WorkflowActivationError

Cause: A workflow's trigger node failed to register (e.g., webhook conflict, invalid schedule).

Solution:

  1. Check the activation error via GET /active-workflows/error/:id
  2. Fix the trigger node configuration
  3. Deactivate and reactivate the workflow

Error: WebhookPathTakenError

Cause: Two workflows use the same webhook path.

Solution:

  1. Change the webhook path on one of the workflows
  2. Deactivate the conflicting workflow

Error: TaskRunnerAcceptTimeoutError / TaskRunnerExecutionTimeoutError

Cause: Code node execution exceeded the configured timeout, or no runner was available.

Solution:

  1. Increase N8N_RUNNERS_TASK_TIMEOUT
  2. Check that task runners are running and connected
  3. Verify N8N_RUNNERS_AUTH_TOKEN matches between broker and runner

Error: UnrecognizedNodeTypeError / UnrecognizedCredentialTypeError

Cause: A workflow references a node or credential type that is not installed.

Solution:

  1. Install the missing community node package
  2. Check that the node is compatible with the current n8n version

Error: ConfigurationError: Environment variable N8N_RUNNERS_GRANT_TOKEN is required

Cause: Python task runner started without the required grant token.

Solution:

  1. Set N8N_RUNNERS_GRANT_TOKEN to match the broker's auth token
  2. Ensure the runner can reach the broker at N8N_RUNNERS_TASK_BROKER_URI

Error: CircuitBreakerOpen

Cause: An external service has been failing consistently and the circuit breaker tripped.

Solution:

  1. Check the external service's availability
  2. The circuit breaker will automatically close after the configured cooling period
  3. Check logs for the underlying failure cause

Note

The circuit breaker pattern is used for log streaming destinations and external service integrations. It prevents cascading failures by temporarily stopping requests to failing services.

Worker not processing jobs

Cause: Worker cannot connect to Redis or is not in queue mode.

Solution:

  1. Verify EXECUTIONS_MODE=queue is set on the worker
  2. Check Redis connectivity: QUEUE_BULL_REDIS_HOST
  3. Check worker logs for connection errors
  4. Verify N8N_ENCRYPTION_KEY matches the main instance

Warning

Running a worker without EXECUTIONS_MODE=queue will start n8n in regular mode, not as a worker. The worker command requires queue mode to be explicitly enabled.


Reference

License Feature Flags

Flag Feature
feat:sharing Workflow/credential sharing
feat:ldap LDAP authentication
feat:saml SAML SSO
feat:oidc OpenID Connect SSO
feat:mfaEnforcement MFA enforcement
feat:logStreaming Log streaming to external destinations
feat:sourceControl Git-based workflow versioning
feat:externalSecrets External secret management
feat:binaryDataS3 S3 binary data storage
feat:multipleMainInstances Multi-main HA
feat:workerView Worker management UI
feat:advancedPermissions Granular RBAC
feat:aiAssistant AI assistant
feat:aiCredits AI credits
feat:aiGateway AI gateway (managed credentials)
feat:aiBuilder AI workflow builder
feat:folders Folder organization
feat:customRoles Custom permission roles
feat:dynamicCredentials Dynamic credential resolution
feat:dataRedaction Data redaction in logs
feat:tokenExchange Token exchange

Node Type Constants

Constant Value
MANUAL_TRIGGER_NODE_TYPE Manual Trigger
WEBHOOK_NODE_TYPE Webhook
HTTP_REQUEST_NODE_TYPE HTTP Request
CODE_NODE_TYPE Code
FORM_NODE_TYPE Form
WAIT_NODE_TYPE Wait
STICKY_NODE_TYPE Sticky Note

Supported Code Languages

Language Identifier
JavaScript javaScript
Python python
JSON json
HTML html