tva
← Insights

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 challenges that n8n Cloud users usually don’t have to manage – 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 a 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 supplies 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 Users Rarely Deal with These Problems

On n8n Cloud, n8n manages server configuration such as webhook URLs, binary data storage, and updates for you. When you self-host, you’re responsible for these configurations.

The Root Causes

Issue #1: Execution Data Size Limit

The default 16 MiB limit for request payloads sent to the backend, including partial execution data, 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 running behind a 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 request to 16 MiB (N8N_PAYLOAD_SIZE_MAX=16; the value is in MiB) to prevent memory issues on smaller servers. If the request is larger, n8n (or a reverse proxy with a smaller body limit) responds with HTTP 413, and the editor shows this error.

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 to Set (MiB)Percentage of RAM
2GB or less64MB64~3%
4GB128MB128~3%
8GB256MB256~3%
16GB+512MB512~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; value in MiB)
      - N8N_PAYLOAD_SIZE_MAX=256

      # 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: This mode stores files (images, PDFs, etc.) in RAM, wastes memory, is not suitable for production workloads, and limits how many files you can process.

From our testing: Default mode used ~315MB RAM at idle vs 211MB with filesystem mode – that’s ~100MB lower idle memory.

Recommended: Filesystem Storage

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

Benefits: This mode stores files on disk instead of RAM, offers significantly better performance with large files, and is production-ready and recommended by n8n. Note that N8N_BINARY_DATA_TTL has had no effect since n8n 1.9.0: n8n deletes binary data when it prunes executions, so the execution pruning settings control disk usage.

Important: If you use queue mode (Redis-based distributed execution), note that n8n doesn’t support filesystem mode there. As of October 2026, n8n’s documentation recommends database mode for 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: In our idle measurements, the configuration with the payload fix and filesystem binary mode used less memory than the default. We did not measure memory under large-payload load, where usage depends on your workflows.


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.

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
  • Appears in the browser address bar and email invitations

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

  • Not a documented n8n variable: it does not appear in n8n’s environment variable reference, so setting it has no documented effect
  • Trusting proxy headers (for real client IP addresses) is controlled by N8N_PROXY_HOPS
  • You can omit it from the examples in this guide

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

The 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, native WebSocket support for the n8n editor’s live connection, 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]

WebSocket Support

Traefik proxies WebSocket connections natively, including the live connection the n8n editor uses, so no extra middleware is required. Webhooks are ordinary HTTPS requests and do not depend on WebSockets. The production example below includes optional WebSocket header labels; you can omit them.

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 in bytes (256MB, matches N8N_PAYLOAD_SIZE_MAX)
      - "traefik.http.middlewares.n8n-buffering.buffering.maxRequestBodyBytes=268435456"

      # Middleware: WebSocket headers (optional; Traefik proxies WebSockets natively)
      - "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=256  # 256 MiB

      # 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: [email protected]  # 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. This only works if you also set api.insecure: true in traefik.yml (for testing only); otherwise, configure a router for the dashboard (api@internal) on its own domain.

You should see:

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

Check n8n Access

Visit https://n8n.yourdomain.com

You should see:

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

Check Webhook URLs

  1. Sign in to 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 a task runner as a child process – this is the simplest configuration, requires no additional infrastructure, is suitable for most self-hosted deployments, and has minimal performance overhead. As of October 2026, n8n’s documentation describes internal mode as insecure by design and deprecates it from n8n 3.0.

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 and enable horizontal scaling across multiple servers, and run as a sidecar container from the n8nio/runners image, whose version must match your n8n image. A Docker Compose setup is enough; Docker Swarm or Kubernetes are not required.

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_URLString–Public webhook URLREQUIRED with reverse proxy
N8N_PAYLOAD_SIZE_MAXNumber16 (MiB)Max request payload size in MiB, including partial execution dataREQUIRED for large data
N8N_RUNNERS_ENABLEDBooleanfalseEnable task runnersRecommended on 1.x (not needed from n8n 2.0)
N8N_TRUST_PROXY_HEADER––Not in n8n’s documented variablesNot needed; use N8N_PROXY_HOPS
Webhook Configuration
N8N_EDITOR_BASE_URLString–Editor 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_TTL––No effect since n8n 1.9.0 (binary data is pruned with executions)Safe to remove
Task Runners
N8N_RUNNERS_MODEStringinternalTask runner modeIf runners enabled
N8N_RUNNERS_MAX_CONCURRENCYNumber10Max concurrent tasks per runnerOptional

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=256  # 256 MiB
  - 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. The examples use the latest image tag; pin n8nio/n8n:1.115.2 to reproduce the tested version.

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: At idle, the production configuration with all fixes used less memory than the default configuration in our tests. These are idle measurements, not results under large-payload load.


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. Sign in to the n8n web interface
  2. Create a new workflow
  3. Add a Webhook node
  4. Check the 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=256


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. 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=256

Solutions:

  1. Variable not applied (container not recreated): Recreate the container to apply changes: docker compose up -d n8n (docker compose restart does not apply changed environment values). 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=512
  3. Traefik request size too small: Also increase the Traefik limit (in bytes) to match: "traefik.http.middlewares.n8n-buffering.buffering.maxRequestBodyBytes=536870912"

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. Impact: ~100MB lower idle memory in 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 the 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, health checks, 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=256 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 (about 100MB lower idle memory in our tests)

For Production Deployment:

  • Use our complete docker-compose.yml with Traefik configuration
  • No WebSocket middleware needed – Traefik proxies WebSockets natively, and webhooks are plain HTTPS requests
  • Include PostgreSQL for better performance under load
  • Set appropriate resource limits based on your server capacity
  • Implement health checks so monitoring and dependent services can detect failures (plain Docker marks a container unhealthy but does not restart it)

For Traefik Users (CRITICAL):

  • Traefik handles WebSockets without extra middleware; webhooks need a correct router and WEBHOOK_URL
  • 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 a .env file with your domain and secure passwords
    • Start Traefik first, then n8n
    • Run post-deployment tests
  3. Validate:
    • Verify HTTPS works with a valid certificate
    • Check webhook URLs show correct format
    • Test with a large dataset (if needed)
    • Confirm task runners are registered
  4. Monitor:
    • Watch resource usage with docker stats
    • Set up health-check alerts (external monitoring)
    • Implement log rotation to prevent the disk from filling up
    • 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 the 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

Further Reading