Complete n8n Self-Hosted Troubleshooting Guide 2025: Fixing Execution Data Size & Webhook Problems with Traefik

Last Updated: October 15, 2025

Self-hosting n8n delivers unlimited workflow executions, complete data control, and significant cost savings compared to cloud plans. But in reality, self-hosted instances face unique challenges that cloud users never encounter – specifically around large data handling and webhook configuration with reverse proxies.

In June 2025, we published two troubleshooting guides addressing these issues separately. The problem is that no comprehensive guide exists for production n8n deployments with Traefik reverse proxy that addresses both common issues together.

This guide combines both original fixes, provides complete Traefik configuration with WebSocket support, includes 2025’s new task runner requirements, and delivers production-ready docker-compose files you can deploy immediately.


Table of Contents

  1. Quick Diagnosis: Which Issue Do You Have?
  2. Understanding the Two Main Issues
  3. Fix #1: Execution Data Too Large Error
  4. Fix #2: Webhook URL Problems
  5. Complete Production Setup with Traefik
  6. 2025 Requirement: Task Runners
  7. Environment Variables Reference
  8. Docker Compose Examples
  9. Testing Your Setup
  10. Troubleshooting Common Issues

Quick Diagnosis: Which Issue Do You Have?

Symptom: “Existing execution data is too large”

You see this error when:

  • Clicking “Execute Node” during workflow development
  • Testing workflows with large datasets or many items
  • Using partial execution mode (testing individual nodes)
  • Processing complex transformations with multiple branches

You need: Fix #1: Execution Data Size


Symptom: Webhooks show incorrect URLs or fail to work

You see this when:

  • Webhook URLs display with port numbers (e.g., :5678)
  • External services (Slack, GitHub, Stripe) can’t reach your webhooks
  • Webhooks work in test mode but fail in production
  • You’re using a reverse proxy (Nginx, Traefik, Caddy)

You need: Fix #2: Webhook URL Configuration


Symptom: Deprecation warnings about task runners

You see logs saying:

Running n8n without task runners is deprecated. Task runners will be
turned on by default in a future version.

You need: Task Runners Configuration


Symptom: You want a complete, production-ready setup

You need:

  • Both fixes applied correctly
  • Traefik reverse proxy with automatic HTTPS
  • Production best practices and security
  • Resource limits and proper monitoring

Jump to: Complete Production Setup


Understanding the Two Main Issues

Why n8n Cloud Doesn’t Have These Problems

n8n Cloud automatically handles higher memory limits for partial execution, correct webhook URLs, optimized binary data storage, and automatic updates including all new requirements. When you self-host, you’re responsible for these configurations.

The Root Causes

Issue #1: Execution Data Size Limit

The default 16MB limit for partial execution data sent to backend triggers errors when working with large datasets, many workflow branches, or complex transformations. The problem is that workflow development becomes frustrating – you can’t test individual nodes during development. The fix is straightforward: the environment variable N8N_PAYLOAD_SIZE_MAX.

Issue #2: Webhook URL Generation

n8n attempts to auto-detect your public URL, but this auto-detection fails when behind reverse proxy. External services receive incorrect webhook URLs with ports or internal hostnames – integrations break silently. The fix: the environment variable WEBHOOK_URL.


Fix #1: Execution Data Too Large Error

The Problem in Detail

When you execute just part of a workflow (clicking “Execute Node” in the editor), n8n needs to load previous execution data to provide context to that node. By default, n8n limits this data transfer to 16MB to prevent memory issues on smaller servers.

The Error Message

According to official n8n documentation:

Please execute the whole workflow, rather than just the node.
(Existing execution data is too large.)

This error appears when processing thousands of items in a single node, working with large JSON API responses, transforming big datasets with Code nodes, or using workflows with many parallel branches.

The Solution: N8N_PAYLOAD_SIZE_MAX

The fix is simple but requires understanding your server’s available resources.

Recommended Settings by Server RAM

Server RAMN8N_PAYLOAD_SIZE_MAXValue in BytesPercentage of RAM
2GB or less64MB67108864~3%
4GB128MB134217728~3%
8GB256MB268435456~3%
16GB+512MB536870912~3%

Rule of Thumb: Use less than 20% of your available RAM to keep the system stable under load.

Docker Compose Implementation

version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_PORT=5678

      # Payload size fix (256MB for 8GB+ RAM servers)
      - N8N_PAYLOAD_SIZE_MAX=268435456

      # Binary data optimization (highly recommended)
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
      - N8N_BINARY_DATA_TTL=1440  # 24 hours

    volumes:
      - n8n_data:/home/node/.n8n

    # Resource limits (adjust based on your server)
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 1G

volumes:
  n8n_data:

Understanding Binary Data Mode

Default: In-Memory Storage (Not Recommended)

# This is the default - DON'T use in production
N8N_DEFAULT_BINARY_DATA_MODE=default

Problems: Stores files (images, PDFs, etc.) in RAM, wastes precious memory, not suitable for production workloads, limits how many files you can process.

From our testing: Default mode uses ~315MB RAM vs 211MB with filesystem mode – that’s ~100MB RAM saved.

Recommended: Filesystem Storage

N8N_DEFAULT_BINARY_DATA_MODE=filesystem
N8N_BINARY_DATA_TTL=1440  # Clean up after 24 hours (value in minutes)

Benefits: Stores files on disk instead of RAM, significantly better performance with large files, production-ready and recommended by n8n, automatic cleanup with TTL prevents disk bloat.

Important: If using queue mode (Redis-based distributed execution), you must keep the default binary data mode as filesystem storage is not supported with queue mode.

Real-World Impact

From our Docker testing in October 2025 with n8n version 1.115.2:

ConfigurationMemory UsageDifference
Default (no fixes)315 MBBaseline
With payload fix + filesystem mode211 MB-104 MB

Key Finding: The combination of increased payload size and filesystem binary mode actually reduces memory usage because data is handled more efficiently on disk rather than in RAM.


Fix #2: Webhook URL Problems

The Problem in Detail

When n8n generates webhook URLs to display in the editor and register with external services, it attempts to auto-detect your public URL. Behind a reverse proxy, this auto-detection fails spectacularly.

What You’ll See (The Wrong URLs)

http://n8n.yourdomain.com:5678/webhook/abc123

Problems with this URL:

  1. Port number included (:5678) – external services typically can’t reach non-standard ports
  2. Wrong protocol (http vs https) – many services require HTTPS
  3. Internal hostname – might be Docker container name instead of public domain

Why External Services Fail

Services like GitHub, Slack, Stripe, Zoom, Google Sheets, and hundreds of others try to send webhooks to these incorrect URLs and fail silently. You set up the integration, it looks correct in the UI, but notifications never arrive.

The Solution: WEBHOOK_URL Environment Variable

According to official n8n documentation:

“The WEBHOOK_URL environment variable is used to manually set the webhook URL so that n8n can display it in the editor UI and register the correct webhook URLs with external services. When running n8n behind a reverse proxy, it’s important to set this variable.”

Basic Configuration

environment:
  - WEBHOOK_URL=https://n8n.yourdomain.com
  - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
  - N8N_PROTOCOL=https
  - N8N_HOST=n8n.yourdomain.com
  - N8N_TRUST_PROXY_HEADER=true
  - N8N_PROXY_HOPS=1

What Each Variable Does

WEBHOOK_URL (MOST IMPORTANT)

  • The public URL for all webhook endpoints
  • Used when registering webhooks with external services
  • Must exactly match your Traefik/reverse proxy configuration
  • Version note: Renamed from WEBHOOK_TUNNEL_URL in v0.227.0, old name removed in n8n 1.0

N8N_EDITOR_BASE_URL

  • The URL for accessing the n8n web interface
  • Usually the same as WEBHOOK_URL
  • Shows in browser address bar and email invites

N8N_PROTOCOL

  • Set to https for production (with SSL/TLS)
  • Set to http only for local testing
  • Must match your reverse proxy termination

N8N_HOST

  • Your public domain name only
  • Don’t include protocol (https://) or port
  • Example: n8n.yourdomain.com not https://n8n.yourdomain.com:443

N8N_TRUST_PROXY_HEADER

  • Must be true when behind reverse proxy
  • Allows n8n to see real client IP addresses from proxy headers
  • Required for proper request handling and security

N8N_PROXY_HOPS

  • Set to 1 when behind one reverse proxy
  • Set to 2 if behind two proxies (rare)
  • Tells n8n how many proxy layers to trust

Testing Webhook URLs

Before the Fix

In the n8n UI, create a Webhook node and check the URL shown:

http://n8n.example.com:5678/webhook/abc123  ❌ Wrong

After the Fix

Same webhook node now displays:

https://n8n.example.com/webhook/abc123  ✅ Correct

Critical difference: External services can now reach this URL because it uses standard HTTPS port 443 (handled by your reverse proxy) instead of internal port 5678.


Complete Production Setup with Traefik

Why Traefik?

Traefik is a modern reverse proxy perfectly suited for Docker deployments – automatic HTTPS via Let’s Encrypt with no manual certificate management, service discovery that automatically detects containers via Docker labels, WebSocket support critical for n8n webhook functionality, easy configuration with just Docker labels instead of complex config files, and a built-in dashboard to monitor routing and certificates in real-time.

Architecture Overview

Internet
  ↓
[Traefik Reverse Proxy]
  ↓ HTTPS (Let's Encrypt)
  ↓ WebSocket Support

[n8n Container]

↓ Internal Network [PostgreSQL Database]

Critical Configuration: WebSocket Support

This is the most commonly missed configuration and causes webhook failures:

labels:
  # WebSocket middleware (ABSOLUTELY REQUIRED)
  - "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Upgrade=websocket"
  - "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Connection=Upgrade"

  # Apply middleware to router
  - "traefik.http.routers.n8n.middlewares=n8n-websocket"

Without WebSocket headers:

  • ❌ Real-time webhooks fail
  • ❌ Production webhooks timeout
  • ❌ External services can’t maintain persistent connections
  • ❌ Integration errors appear intermittently and unpredictably

Complete Production Docker Compose

This configuration combines both fixes, includes Traefik with proper WebSocket support, and follows production best practices:

version: '3.8'

networks:
  traefik-net:
    external: true
  n8n-internal:
    internal: true

services:
  # PostgreSQL Database
  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    networks:
      - n8n-internal
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 512M

  # n8n Application
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - traefik-net
      - n8n-internal

    # Traefik Configuration Labels
    labels:
      # Enable Traefik for this container
      - "traefik.enable=true"
      - "traefik.docker.network=traefik-net"

      # Router configuration
      - "traefik.http.routers.n8n.rule=Host(`${N8N_DOMAIN}`)"
      - "traefik.http.routers.n8n.entrypoints=websecure"
      - "traefik.http.routers.n8n.tls.certresolver=letsencrypt"

      # Service configuration
      - "traefik.http.services.n8n.loadbalancer.server.port=5678"

      # Middleware: Request size limit (100MB)
      - "traefik.http.middlewares.n8n-buffering.buffering.maxRequestBodyBytes=104857600"

      # Middleware: WebSocket support (CRITICAL - DO NOT SKIP)
      - "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Upgrade=websocket"
      - "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Connection=Upgrade"

      # Middleware: Security headers
      - "traefik.http.middlewares.n8n-security.headers.customResponseHeaders.X-Robots-Tag=noindex,nofollow"
      - "traefik.http.middlewares.n8n-security.headers.sslProxyHeaders.X-Forwarded-Proto=https"

      # Apply ALL middlewares
      - "traefik.http.routers.n8n.middlewares=n8n-buffering,n8n-websocket,n8n-security"

    environment:
      # Database Configuration
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}

      # FIX #2: Webhook URL Configuration
      - WEBHOOK_URL=https://${N8N_DOMAIN}
      - N8N_EDITOR_BASE_URL=https://${N8N_DOMAIN}
      - N8N_PROTOCOL=https
      - N8N_HOST=${N8N_DOMAIN}
      - N8N_PORT=5678
      - N8N_TRUST_PROXY_HEADER=true
      - N8N_PROXY_HOPS=1

      # FIX #1: Payload Size Configuration
      - N8N_PAYLOAD_SIZE_MAX=268435456  # 256MB

      # Binary Data Management
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
      - N8N_BINARY_DATA_TTL=1440  # 24 hours

      # 2025 Requirement: Task Runners
      - N8N_RUNNERS_ENABLED=true
      - N8N_RUNNERS_MODE=internal
      - N8N_RUNNERS_MAX_CONCURRENCY=5

      # Production Optimizations
      - NODE_ENV=production
      - EXECUTIONS_DATA_MAX_AGE=168  # 7 days
      - EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
      - N8N_LOG_LEVEL=info
      - N8N_LOG_OUTPUT=console

      # Timezone (adjust to your location)
      - GENERIC_TIMEZONE=America/New_York
      - TZ=America/New_York

      # Security
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

    volumes:
      - n8n_data:/home/node/.n8n

    # Resource Limits (8GB+ RAM server)
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '2.0'
        reservations:
          memory: 1G
          cpus: '1.0'

    # Health Check
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5678/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  n8n_data:
  postgres_data:

Traefik Setup

If you don’t have Traefik running yet, here’s the complete setup:

Step 1: Create Traefik Network

docker network create traefik-net

Step 2: Create Traefik Configuration

Create traefik/traefik.yml:

api:
  dashboard: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-net

certificatesResolvers:
  letsencrypt:
    acme:
      email: your-email@example.com  # CHANGE THIS
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

log:
  level: INFO

accessLog: {}

Step 3: Create Traefik Docker Compose

Create traefik/docker-compose.yml:

version: '3.8'

networks:
  traefik-net:
    external: true

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - traefik-net
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard (secure this in production!)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/traefik.yml:ro
      - ./letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"

Step 4: Create Environment File

Create .env in your n8n directory:

# Domain Configuration
N8N_DOMAIN=n8n.yourdomain.com

# Database Password (generate secure password)
DB_PASSWORD=your_secure_db_password_here

# n8n Encryption Key (generate random string)
N8N_ENCRYPTION_KEY=your_encryption_key_here

Generate secure values:

# For DB_PASSWORD
openssl rand -base64 32

# For N8N_ENCRYPTION_KEY
openssl rand -hex 32

Step 5: Launch Everything

# Start Traefik first
cd traefik
docker compose up -d

# Wait a few seconds, then start n8n
cd ../n8n
docker compose up -d

# Watch logs to verify startup
docker compose logs -f n8n

Verifying Your Setup

Check Traefik Dashboard

Visit http://your-server-ip:8080 (or configure domain for dashboard)

Should show:

  • ✅ n8n router active with green status
  • ✅ Certificate obtained from Let’s Encrypt
  • ✅ Service marked as healthy

Check n8n Access

Visit https://n8n.yourdomain.com

Should show:

  • ✅ HTTPS working with valid Let’s Encrypt certificate
  • ✅ No browser security warnings
  • ✅ n8n login/setup page appears correctly

Check Webhook URLs

  1. Log into n8n
  2. Create a new workflow
  3. Add a Webhook node
  4. Check the “Production URL” shown

Expected:

https://n8n.yourdomain.com/webhook/abc123

NOT this (means configuration is wrong):

http://n8n.yourdomain.com:5678/webhook/abc123  ❌

2025 Requirement: Task Runners

What Are Task Runners?

Task runners execute code defined in Code nodes within isolated processes instead of the main n8n process. This provides better security through sandboxed environments, improved stability where code errors don’t crash the main process, and future compatibility as they’re required in upcoming n8n versions.

Why This Matters Now

From official n8n documentation:

“Running n8n without task runners is deprecated. Task runners will be turned on by default in a future version. Users are advised to set N8N_RUNNERS_ENABLED=true now to avoid potential issues in the future.”

From our testing logs (October 2025):

There are deprecations related to your environment variables:
 - N8N_RUNNERS_ENABLED -> Running n8n without task runners is deprecated.

Configuration

Internal Mode (Recommended for Single Server)

environment:
  - N8N_RUNNERS_ENABLED=true
  - N8N_RUNNERS_MODE=internal
  - N8N_RUNNERS_MAX_CONCURRENCY=5

n8n launches task runner as child process – simplest configuration with no additional infrastructure needed, suitable for most self-hosted deployments, minimal performance overhead.

External Mode (For Distributed Setups)

environment:
  - N8N_RUNNERS_ENABLED=true
  - N8N_RUNNERS_MODE=external
  - N8N_RUNNERS_AUTH_TOKEN=your_secure_token

Separate task runner containers provide better resource isolation for high-volume workflows, enable horizontal scaling across multiple servers, but require orchestration (Docker Swarm, Kubernetes).

Verifying Task Runners

Check Process List

docker exec n8n ps aux

Without task runners (3 processes):

PID   USER     TIME  COMMAND
    1 node      0:00 tini -- /docker-entrypoint.sh
    7 node      0:12 node /usr/local/bin/n8n

With task runners (4 processes):

PID   USER     TIME  COMMAND
    1 node      0:00 tini -- /docker-entrypoint.sh
    7 node      0:16 node /usr/local/bin/n8n
   18 node      0:10 node [...]/task-runner/dist/start.js

Evidence: Task runner process visible with PID 18.

Check Logs

docker logs n8n | grep -i runner

Should see:

n8n Task Broker ready on 127.0.0.1, port 5679
Registered runner "JS Task Runner" (zCWpF0Eb_LJsqWYvLm5t1)

Impact on Resource Usage

From our Docker testing (October 2025, n8n version 1.115.2):

ConfigurationMemoryCPUProcesses
Without task runners214 MB0.14%3
With task runners289 MB0.29%4
Difference+75 MB+0.15%+1

Minimal overhead. The benefits – security, stability, future-proofing – far outweigh the small resource cost.


Environment Variables Reference

Complete Variable List

VariableTypeDefaultPurposePriority
Critical Variables
WEBHOOK_URLStringPublic webhook URLREQUIRED with reverse proxy
N8N_PAYLOAD_SIZE_MAXNumber16777216(16MB)Max execution data sizeREQUIRED for large data
N8N_RUNNERS_ENABLEDBooleanfalseEnable task runnersREQUIRED for 2025
N8N_TRUST_PROXY_HEADERBooleanfalseTrust reverse proxy headersREQUIRED with proxy
Webhook Configuration
N8N_EDITOR_BASE_URLStringEditor UI URLRecommended
N8N_PROTOCOLStringhttpProtocol (http/https)Production
N8N_HOSTStringlocalhostPublic hostnameProduction
N8N_PORTNumber5678Internal portOptional
N8N_PROXY_HOPSNumber0Number of reverse proxiesSet to 1 with proxy
Performance
N8N_DEFAULT_BINARY_DATA_MODEStringdefaultBinary storage modeRecommended
N8N_BINARY_DATA_TTLNumber60Binary cleanup (minutes)Recommended
Task Runners
N8N_RUNNERS_MODEStringinternalTask runner modeIf runners enabled
N8N_RUNNERS_MAX_CONCURRENCYNumber5Max concurrent task runnersOptional

Configuration Presets by Scenario

Scenario A: Development (Local Machine)

environment:
  - N8N_PORT=5678

Use when: Testing locally, no reverse proxy, no production requirements

Scenario B: Behind Reverse Proxy (No Large Data)

environment:
  - N8N_PORT=5678
  - WEBHOOK_URL=https://n8n.yourdomain.com
  - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
  - N8N_PROTOCOL=https
  - N8N_HOST=n8n.yourdomain.com
  - N8N_TRUST_PROXY_HEADER=true
  - N8N_PROXY_HOPS=1
  - N8N_RUNNERS_ENABLED=true

Use when: Public n8n instance, webhooks needed, smaller workflows

Scenario C: Complete Production Setup

environment:
  # 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}

  # Webhooks
  - WEBHOOK_URL=https://n8n.yourdomain.com
  - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
  - N8N_PROTOCOL=https
  - N8N_HOST=n8n.yourdomain.com
  - N8N_PORT=5678
  - N8N_TRUST_PROXY_HEADER=true
  - N8N_PROXY_HOPS=1

  # Performance
  - N8N_PAYLOAD_SIZE_MAX=268435456  # 256MB
  - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
  - N8N_BINARY_DATA_TTL=1440

  # Task Runners
  - N8N_RUNNERS_ENABLED=true
  - N8N_RUNNERS_MODE=internal
  - N8N_RUNNERS_MAX_CONCURRENCY=5

  # Production
  - NODE_ENV=production
  - EXECUTIONS_DATA_MAX_AGE=168  # 7 days
  - EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
  - N8N_LOG_LEVEL=info

  # Security
  - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

Use when: Production deployment with all features, large workflows, public access


Docker Compose Examples

All four scenarios from our testing environment are available. These configurations have been validated with n8n version 1.115.2 in October 2025.

Resource Usage Comparison (From Our Tests)

ScenarioMemoryCPUProcessesDescription
Default315 MB0.00%3No fixes, baseline
Payload Fix211 MB0.00%3Payload + filesystem mode
Webhook Fix215 MB0.14%3Webhook config only
Production289 MB0.29%4All fixes + task runners

Key Insight: The production configuration with all fixes uses LESS memory than default configuration due to filesystem binary mode.


Testing Your Setup

Pre-Deployment Checklist

1. DNS Configuration

# Verify DNS points to your server
nslookup n8n.yourdomain.com

# Should return your server's public IP

2. Port Availability

# Check if required ports are free
sudo netstat -tlnp | grep -E '(80|443|5678)'

# Should show nothing or only Traefik on 80/443

3. Docker Installation

# Verify Docker
docker --version

# Verify Docker Compose
docker compose version

4. Environment Variables

# Verify .env file exists
cat .env

# Should show N8N_DOMAIN, DB_PASSWORD, N8N_ENCRYPTION_KEY

Deployment Steps

# Step 1: Create Traefik network
docker network create traefik-net

# Step 2: Start Traefik
cd traefik
docker compose up -d

# Step 3: Wait for Traefik to be ready
sleep 10

# Step 4: Start n8n
cd ../n8n
docker compose up -d

# Step 5: Watch logs for any errors
docker compose logs -f n8n

Post-Deployment Tests

Test 1: HTTPS Access

curl -I https://n8n.yourdomain.com

Expected: HTTP/2 200 (or HTTP/1.1 200)

Test 2: HTTP to HTTPS Redirect

curl -I http://n8n.yourdomain.com

Expected: HTTP/1.1 308 Permanent Redirect with Location: https://n8n.yourdomain.com

Test 3: Container Health

docker ps

Expected: Both n8n and n8n-postgres showing (healthy) status

Test 4: Webhook URL Format

  1. Log into n8n web interface
  2. Create new workflow
  3. Add Webhook node
  4. Check Production URL shown

Expected format:

https://n8n.yourdomain.com/webhook/abc123

NOT expected (configuration error):

http://n8n.yourdomain.com:5678/webhook/abc123  ❌

Test 5: Task Runners Active

docker logs n8n | grep -i runner

Expected output:

Registered runner "JS Task Runner"

Test 6: Environment Variables Applied

docker exec n8n env | grep N8N_PAYLOAD_SIZE_MAX

Expected: N8N_PAYLOAD_SIZE_MAX=268435456


Troubleshooting Common Issues

Issue: HTTPS Not Working

Symptoms: Browser shows “Not Secure” warning, certificate error messages, can’t access via HTTPS

Diagnosis:

# Check Traefik logs for errors
docker logs traefik | grep -i error

# Check certificate file exists
ls -la traefik/letsencrypt/acme.json

# Verify DNS resolution
nslookup n8n.yourdomain.com

Solutions:

  1. DNS not pointing to server: Update your DNS A record to point to server’s public IP, wait for DNS propagation (up to 24 hours, usually much faster), test from different network: dig n8n.yourdomain.com +short
  2. Port 80 blocked: Let’s Encrypt needs port 80 for HTTP challenge. Check firewall: sudo ufw status. Allow if blocked: sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
  3. Invalid email in Traefik config: Edit traefik/traefik.yml, update certificatesResolvers.letsencrypt.acme.email to valid address, restart Traefik: docker compose restart

Issue: Webhooks Return 404

Symptoms: External services report webhook failures, webhook URLs look correct but don’t work, test mode works but production mode fails

Diagnosis:

# Test webhook directly
curl -v https://n8n.yourdomain.com/webhook/test

# Check Traefik routing logs
docker logs traefik | grep webhook

# Verify n8n sees requests
docker logs n8n | grep webhook

Solutions:

  1. WebSocket middleware missing: Verify these labels in docker-compose.yml:
- "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Upgrade=websocket"
- "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Connection=Upgrade"
- "traefik.http.routers.n8n.middlewares=n8n-websocket"
  1. WEBHOOK_URL not set correctly: Check environment variable: docker exec n8n env | grep WEBHOOK_URL. Should match your domain exactly: WEBHOOK_URL=https://n8n.yourdomain.com
  2. Wrong network configuration: Verify n8n is on traefik-net: docker inspect n8n | grep -A 5 Networks. Should show “traefik-net” in output

Issue: “Execution Data Too Large” Still Appears

Symptoms: Error still occurs after setting N8N_PAYLOAD_SIZE_MAX, large workflows fail at “Execute Node”

Diagnosis:

# Verify variable is set
docker exec n8n env | grep PAYLOAD

# Should show N8N_PAYLOAD_SIZE_MAX=268435456

Solutions:

  1. Variable not applied (container not restarted): Restart to apply changes: docker compose restart n8n. Verify after restart: docker exec n8n env | grep PAYLOAD
  2. Need higher limit for your workflow: For 16GB+ RAM servers, increase to 512MB: N8N_PAYLOAD_SIZE_MAX=536870912
  3. Traefik request size too small: Also increase Traefik limit to match: "traefik.http.middlewares.n8n-buffering.buffering.maxRequestBodyBytes=209715200"

Issue: High Memory Usage

Symptoms: Container using >1.5GB RAM at idle, memory usage grows over time, out of memory errors

Diagnosis:

# Monitor memory
docker stats n8n

# Check binary data mode
docker exec n8n env | grep BINARY_DATA_MODE

Solutions:

  1. Not using filesystem mode: Add to environment: N8N_DEFAULT_BINARY_DATA_MODE=filesystem and N8N_BINARY_DATA_TTL=1440Impact: Saves ~100MB RAM based on our testing
  2. Old executions accumulating: Reduce retention period: EXECUTIONS_DATA_MAX_AGE=168 (7 days instead of 14) and EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
  3. Container limit too low: Increase if server has capacity. Change memory limit from 2G to 4G in deploy resources section

Conclusion

What We’ve Solved

This comprehensive guide addresses the two most common self-hosted n8n issues:

  1. ✅ Execution Data Too Large Error – Fixed with N8N_PAYLOAD_SIZE_MAX and filesystem binary mode
  2. ✅ Webhook URL Problems – Fixed with WEBHOOK_URL and proper reverse proxy configuration

Plus these critical additions:

  1. ✅ Complete Traefik Setup – Production-ready configuration with WebSocket support
  2. ✅ Task Runners Configuration – 2025 requirement for future compatibility
  3. ✅ Production Best Practices – Resource limits, healthchecks, security headers, monitoring
  4. ✅ Validated Configurations – All docker-compose files tested with n8n 1.115.2 in October 2025

Key Takeaways

For Quick Fixes:

  • Set N8N_PAYLOAD_SIZE_MAX=268435456 for execution data issues (256MB for 8GB+ RAM)
  • Set WEBHOOK_URL=https://your-domain.com for webhook problems
  • Set N8N_RUNNERS_ENABLED=true to eliminate deprecation warnings
  • Use N8N_DEFAULT_BINARY_DATA_MODE=filesystem to save ~100MB RAM

For Production Deployment:

  • Use our complete docker-compose.yml with Traefik configuration
  • Don’t skip WebSocket middleware – absolutely required for webhooks
  • Include PostgreSQL for better performance under load
  • Set appropriate resource limits based on your server capacity
  • Implement healthchecks for automatic recovery

For Traefik Users (CRITICAL):

  • WebSocket middleware is non-negotiable for webhook functionality
  • Set request body size limit to match or exceed payload size
  • Configure security headers (X-Robots-Tag, X-Forwarded-Proto)
  • Ensure DNS points to your server before starting Traefik (Let’s Encrypt requirement)

What’s New Compared to June 2025 Posts

FeatureJune 2025 PostsThis Guide
Execution data fix✅ Detailed✅ Included + resource measurements
Webhook fix✅ Detailed✅ Included + Traefik integration
Traefik configuration❌ Not covered✅ Complete setup
WebSocket support❌ Not covered✅ Emphasized
Task runners❌ Not covered✅ 2025 requirement
Combined docker-compose❌ Separate✅ Production-ready
Resource measurements❌ Theoretical✅ Actual test data
Environment variables✅ Covered✅ Complete reference

Testing and Validation

Our testing environment (October 2025):

  • ✅ n8n version 1.115.2
  • ✅ Docker containers running for 2+ hours
  • ✅ All environment variables verified in running containers
  • ✅ Resource usage measured with docker stats
  • ✅ Task runner process confirmed in process list
  • ✅ HTTP endpoints tested and accessible
  • ✅ Configurations validated as working

Next Steps

  1. Choose your scenario:
    • Development: Minimal configuration
    • Behind reverse proxy: Webhook fix + task runners
    • Production: Complete setup with Traefik (recommended)
  2. Deploy:
    • Copy the appropriate docker-compose.yml
    • Create .env file with your domain and secure passwords
    • Start Traefik first, then n8n
    • Run post-deployment tests
  3. Validate:
    • Verify HTTPS works with valid certificate
    • Check webhook URLs show correct format
    • Test with large dataset (if needed)
    • Confirm task runners are registered
  4. Monitor:
    • Watch resource usage with docker stats
    • Set up healthcheck alerts (external monitoring)
    • Implement log rotation to prevent disk filling
    • Plan regular backups of data volumes

Related Resources

From June 2025:

Official n8n Documentation:

Questions or Issues?

If you encounter problems not covered in this guide:

  1. Review our June 2025 detailed troubleshooting posts for additional guidance
  2. Consult official n8n documentation for latest features
  3. Search n8n Community forums for similar issues
  4. Check the Troubleshooting section above for common problems
  5. Contact tva for professional implementation support

Reproducible Testing

All configurations in this guide can be reproduced in your own environment – Docker Compose files are production-ready, environment variables are documented and verified, test commands are provided for validation, and expected outputs are clearly specified. You can validate every claim in this guide by deploying the configurations yourself and running the provided tests.

Need Help with Implementation?

If you’d like tva to handle your n8n deployment or need assistance with production setup, get in touch with us. We implement these configurations for organizations looking for reliable, production-ready n8n infrastructure.


Published: October 15, 2025
Tested With: n8n v1.115.2, Docker Compose v3.8, Traefik v2.10
Server Requirements: 4GB+ RAM, 2+ CPU cores recommended for production
Based On: Official n8n documentation, validated Docker testing, and community best practices

Scroll to Top