Skip to content
Back to skills

N8n Workflow Automation

ASecurity

Production guidelines for building scalable, resilient n8n workflow automation pipelines. Use when designing self-hosted n8n instances, custom Code nodes (JS/Python), Webhook triggers, error-handling workflows, multi-node queue mode, community node integration, or enterprise credential management.

  • 8 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 29, 2026
ai-agentsjavascriptpythongojavashellsqlnodedockerkubernetesgit

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add hamzabellouch/agent-skills --skill n8n-workflow-automation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of N8n Workflow Automation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for N8n Workflow Automation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hamzabellouch-n8n-workflow-automation/badge)](https://www.skillsdirectory.com/skills/hamzabellouch-n8n-workflow-automation)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: n8n-workflow-automation
metadata:
  category: No-Code Low-Code and Workflow Automation
description: Production guidelines for building scalable, resilient n8n workflow automation pipelines. Use when designing self-hosted n8n instances, custom Code nodes (JS/Python), Webhook triggers, error-handling workflows, multi-node queue mode, community node integration, or enterprise credential management.
compatibility: n8n v1.0+, Node.js 18+, Docker/Kubernetes, PostgreSQL, Redis
---

# n8n Workflow Automation Production Guidelines

This skill provides architectural patterns, custom node development strategies, error-handling topologies, and self-hosted queue deployment standards for enterprise n8n workflow automation environments.

---

## 1. Core Architecture & Scaling Topology

### 1.1 Scaling Modes (Single Instance vs. Queue Mode)

Production n8n deployments scaling beyond basic workloads require **Queue Mode** using Redis and PostgreSQL:

```
                      +-------------------+
                      |   Reverse Proxy   |
                      |   (Nginx / Caddy) |
                      +---------+---------+
                                |
               +----------------+----------------+
               |                                 |
      +--------v-------+                +--------v-------+
      |  n8n Main Web  |                |   n8n Webhook  |
      |   (UI / API)   |                |    Instance    |
      +--------+-------+                +--------+-------+
               |                                 |
               +----------------+----------------+
                                |
                      +---------v---------+
                      |   Redis Broker    |
                      | (Bull Queue / Job)|
                      +---------+---------+
                                |
               +----------------+----------------+
               |                                 |
      +--------v-------+                +--------v-------+
      |  n8n Worker 1  |                |  n8n Worker 2  |
      | (Exec Engine)  |                | (Exec Engine)  |
      +--------+-------+                +--------+-------+
               |                                 |
               +----------------+----------------+
                                |
                      +---------v---------+
                      |    PostgreSQL     |
                      |   (State/Logs)    |
                      +-------------------+
```

- **Main Instance**: Handles UI administration, REST API, workflow creation, and scheduled trigger evaluation.
- **Webhook Instance**: Lightweight dedicated nodes exposing `/webhook/*` endpoints to handle incoming external HTTP payloads without UI overhead.
- **Worker Nodes**: Headless instances consuming jobs from Redis queue, performing heavy data processing and external API calls.
- **PostgreSQL**: Stores persistent workflows, credentials, execution history, and binary data pointers.

### 1.2 Execution Memory & Resource Management

- **Execution Pruning**: In production, execution log retention must be capped to prevent DB bloat:
  ```env
  EXECUTIONS_DATA_PRUNE=true
  EXECUTIONS_DATA_MAX_AGE=168 # hours (7 days)
  EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
  ```
- **Memory Optimization**: Avoid loading large binary files directly into memory. Use disk offloading:
  ```env
  N8N_DEFAULT_BINARY_DATA_MODE=filesystem
  N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
  ```

---

## 2. Custom Code Nodes & Data Context

### 2.1 Data Processing in Code Nodes (JavaScript / Python)

n8n passes data between nodes as an array of JSON objects structured as `[{ json: { ... } }]`.

#### JavaScript Context (`$input`, `$json`, `$vars`)
```javascript
// Access input items array
const items = $input.all();
const processedItems = [];

for (let i = 0; i < items.length; i++) {
  const currentItem = items[i].json;
  
  // Cleanse and transform payload
  processedItems.push({
    json: {
      id: currentItem.id,
      full_name: `${currentItem.first_name || ''} ${currentItem.last_name || ''}`.trim(),
      email: String(currentItem.email || '').toLowerCase(),
      processed_at: new Date().toISOString(),
      metadata: {
        source: 'webhook_ingest',
        workflow_id: $workflow.id,
        execution_id: $executionId
      }
    }
  });
}

return processedItems;
```

#### Python Context
```python
# Access items via _input
input_items = _input.all()
output_items = []

for item in input_items:
    data = item.get("json", {})
    output_items.append({
        "json": {
            "user_id": data.get("id"),
            "score": float(data.get("metrics", {}).get("raw_score", 0)) * 1.5,
            "status": "APPROVED" if data.get("verified") else "PENDING"
        }
    })

return output_items
```

---

## 3. Resilience, Error Handling & Sub-workflows

### 3.1 Global Error Workflows

Every production workflow must configure a dedicated **Error Trigger** workflow:

```
[ Primary Workflow ]                                 [ Error Workflow ]
  Trigger Node                                         Error Trigger Node
       |                                                        |
  Business Logic  -- (On Error) --> Trigger Error Flow ---> Extract Execution ID
       |                                                        |
  Output Action                                        Format Alert (Slack/PagerDuty)
                                                                |
                                                       Log to Sentry / DB
```

### 3.2 Retry Policies & Circuit Breaking

- Set **Continue On Fail** or **Retry On Fail** on network-bound HTTP Request nodes:
  - **Max Tries**: `3`
  - **Wait Between Tries (ms)**: `2000` (Exponential Backoff recommended)
- **Sub-workflow Encapsulation**: Modularize reusable logic (e.g., Auth token refresh, DB write) into dedicated sub-workflows called via `Execute Workflow` node.

---

## 4. Anti-Patterns & Critical Pitfalls

| Anti-Pattern | Severity | Consequence | Correct Pattern |
|---|---|---|---|
| Storing hardcoded secrets in Code Nodes | Critical | Credential leakage in workflow exports / Git | Use n8n Enterprise Credentials or Environment Variables (`$env`) |
| Unbound execution retention (No Pruning) | High | PostgreSQL disk exhaustion, DB query slowdown | Set `EXECUTIONS_DATA_PRUNE=true` with strict age caps |
| Loading large files (>50MB) into JS memory | Critical | Node.js process Out-Of-Memory (OOM) crash | Use `N8N_DEFAULT_BINARY_DATA_MODE=filesystem` |
| Monolithic single workflows (>50 nodes) | Medium | Hard to debug, unmaintainable, memory spikes | Modularize into Sub-workflows with `Execute Workflow` node |
| Polling APIs without state pointers | Medium | Duplicate event processing | Store last sync timestamp/ID using n8n `Static Data` (`$getWorkflowStaticData('global')`) |

---

## 5. Production Infrastructure & Code Templates

### 5.1 Production Docker Compose Topology with Worker Nodes

```yaml
version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${POSTGRES_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

  redis:
    image: redis:7-alpine
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n-main:
    image: n8nio/n8n:latest
    restart: always
    command: start
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=168
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
    ports:
      - "5678:5678"
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  n8n-worker:
    image: n8nio/n8n:latest
    restart: always
    command: worker
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
    depends_on:
      - n8n-main

volumes:
  postgres_data:
```

---

## 6. Verification & Monitoring Checklist

- [ ] **Health Monitoring**: Monitor `/healthz` on main node and ensure Redis queue depth stays near zero.
- [ ] **DB Indexes**: Verify PostgreSQL indexes exist on `execution_entity` (`id`, `startedAt`, `finished`).
- [ ] **Credential Encryption**: Confirm `N8N_ENCRYPTION_KEY` is backed up outside code/Git repositories.
- [ ] **Rate Limiting**: Enforce webserver rate limits on webhook ingestion routes (`/webhook/*`).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…