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
- Quick Diagnosis: Which Issue Do You Have?
- Understanding the Two Main Issues
- Fix #1: Execution Data Too Large Error
- Fix #2: Webhook URL Problems
- Complete Production Setup with Traefik
- 2025 Requirement: Task Runners
- Environment Variables Reference
- Docker Compose Examples
- Testing Your Setup
- 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 RAM | N8N_PAYLOAD_SIZE_MAX | Value to Set (MiB) | Percentage of RAM |
|---|---|---|---|
| 2GB or less | 64MB | 64 | ~3% |
| 4GB | 128MB | 128 | ~3% |
| 8GB | 256MB | 256 | ~3% |
| 16GB+ | 512MB | 512 | ~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:
| Configuration | Memory Usage | Difference |
|---|---|---|
| Default (no fixes) | 315 MB | Baseline |
| With payload fix + filesystem mode | 211 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:
- Port number included (
:5678) – external services typically can’t reach non-standard ports - Wrong protocol (http vs https) – many services require HTTPS
- 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_URLin 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
httpsfor production (with SSL/TLS) - Set to
httponly 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.comnothttps://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
1when behind one reverse proxy - Set to
2if 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
- Sign in to n8n
- Create a new workflow
- Add a Webhook node
- 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):
| Configuration | Memory | CPU | Processes |
|---|---|---|---|
| Without task runners | 214 MB | 0.14% | 3 |
| With task runners | 289 MB | 0.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
| Variable | Type | Default | Purpose | Priority |
|---|---|---|---|---|
| Critical Variables | ||||
WEBHOOK_URL | String | – | Public webhook URL | REQUIRED with reverse proxy |
N8N_PAYLOAD_SIZE_MAX | Number | 16 (MiB) | Max request payload size in MiB, including partial execution data | REQUIRED for large data |
N8N_RUNNERS_ENABLED | Boolean | false | Enable task runners | Recommended on 1.x (not needed from n8n 2.0) |
N8N_TRUST_PROXY_HEADER | – | – | Not in n8n’s documented variables | Not needed; use N8N_PROXY_HOPS |
| Webhook Configuration | ||||
N8N_EDITOR_BASE_URL | String | – | Editor UI URL | Recommended |
N8N_PROTOCOL | String | http | Protocol (http/https) | Production |
N8N_HOST | String | localhost | Public hostname | Production |
N8N_PORT | Number | 5678 | Internal port | Optional |
N8N_PROXY_HOPS | Number | 0 | Number of reverse proxies | Set to 1 with proxy |
| Performance | ||||
N8N_DEFAULT_BINARY_DATA_MODE | String | default | Binary storage mode | Recommended |
N8N_BINARY_DATA_TTL | – | – | No effect since n8n 1.9.0 (binary data is pruned with executions) | Safe to remove |
| Task Runners | ||||
N8N_RUNNERS_MODE | String | internal | Task runner mode | If runners enabled |
N8N_RUNNERS_MAX_CONCURRENCY | Number | 10 | Max concurrent tasks per runner | Optional |
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)
| Scenario | Memory | CPU | Processes | Description |
|---|---|---|---|---|
| Default | 315 MB | 0.00% | 3 | No fixes, baseline |
| Payload Fix | 211 MB | 0.00% | 3 | Payload + filesystem mode |
| Webhook Fix | 215 MB | 0.14% | 3 | Webhook config only |
| Production | 289 MB | 0.29% | 4 | All 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
- Sign in to the n8n web interface
- Create a new workflow
- Add a Webhook node
- 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:
- 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 - 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 - Invalid email in Traefik config: Edit
traefik/traefik.yml, updatecertificatesResolvers.letsencrypt.acme.emailto 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:
- 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 - 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:
- Variable not applied (container not recreated): Recreate the container to apply changes:
docker compose up -d n8n(docker compose restartdoes not apply changed environment values). Verify after restart:docker exec n8n env | grep PAYLOAD - Need higher limit for your workflow: For 16GB+ RAM servers, increase to 512MB:
N8N_PAYLOAD_SIZE_MAX=512 - 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:
- Not using filesystem mode: Add to environment:
N8N_DEFAULT_BINARY_DATA_MODE=filesystem. Impact: ~100MB lower idle memory in our testing - Old executions accumulating: Reduce retention period:
EXECUTIONS_DATA_MAX_AGE=168(7 days instead of 14) andEXECUTIONS_DATA_PRUNE_MAX_COUNT=1000 - 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:
- ✅ Execution Data Too Large Error – Fixed with
N8N_PAYLOAD_SIZE_MAXand filesystem binary mode - ✅ Webhook URL Problems – Fixed with
WEBHOOK_URLand proper reverse proxy configuration
Plus these critical additions:
- ✅ Complete Traefik Setup – Production-ready configuration with WebSocket support
- ✅ Task Runners Configuration – 2025 requirement for future compatibility
- ✅ Production Best Practices – Resource limits, health checks, security headers, monitoring
- ✅ 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=256for execution data issues (256MB for 8GB+ RAM) - Set
WEBHOOK_URL=https://your-domain.comfor webhook problems - Set
N8N_RUNNERS_ENABLED=trueto 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
| Feature | June 2025 Posts | This 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
- Choose your scenario:
- Development: Minimal configuration
- Behind reverse proxy: Webhook fix + task runners
- Production: Complete setup with Traefik (recommended)
- 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
- 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
- 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
- Watch resource usage with
Related Resources
From June 2025:
- Solving n8n “Existing execution data is too large” Error – In-depth troubleshooting guide
- Fixing n8n Webhook Problems – Complete webhook debugging guide
Official n8n Documentation:
- Webhook URL Configuration
- Environment Variables Reference
- Task Runners
- Binary Data Management
- Execution Data Scaling
Questions or Issues?
If you encounter problems not covered in this guide:
- Review our June 2025 detailed troubleshooting posts for additional guidance
- Consult official n8n documentation for the latest features
- Search n8n Community forums for similar issues
- Check the Troubleshooting section above for common problems
- 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