n8n-workflow-patterns
Proven workflow architectural patterns from real n8n workflows. Use when building new workflows, designing workflow structure, choosing workflow patterns, planning workflow architecture, or asking about webhook processing, HTTP API integration, database operations, AI agent workflows, batch processi
By czlonkowski · 10,692 installs
npx skills add czlonkowski/n8n-skills --skill n8n-workflow-patterns
Source repository · Upstream listing
n8n Workflow Patterns
Proven architectural patterns for building n8n workflows.
The 6 Core Patterns
Based on analysis of real workflow usage:
1. [Webhook Processing](webhook processing.md) (Most Common)
Receive HTTP requests → Process → Output
Pattern: Webhook → Validate → Transform → Respond/Notify
2. [HTTP API Integration](http api integration.md)
Fetch from REST APIs → Transform → Store/Use
Pattern: Trigger → HTTP Request → Transform → Action → Error Handler
3. [Database Operations](database operations.md)
Read/Write/Sync database data
Pattern: Schedule → Query → Transform → Write → Verify
4. [AI Agent Workflow](ai agent workflow.md)
AI agents with tools and memory
Pattern: Trigger → AI Agent (Model + Tools + Memory) → Output
5. [Scheduled Tasks](scheduled tasks.md)
Recurring automation workflows
Pattern: Schedule → Fetch → Process → Deliver → Log
6. Batch Processing (below)
Process large datasets in chunks with API rate limits
Pattern: Prepare → SplitInBatches → Process per batch → Accumulate → Aggregate
Pattern Selection Guide
When to use each pattern:
Webhook Processing Use when:
Receiving data from external systems
Building integrations (Slack commands, form submissions, GitHub webhooks)
Need instant response to events
Example: "Receive Stripe payment webhook → Update database → Send confirmation"
HTTP API Integration Use when:
Fetching data from external APIs
Synchronizing with third party services
Building data pipelines
Example: "Fetch GitHub issues → Transform → Create Jira tickets"
Database Operations Use when:
Syncing between databases
Running database queries on schedule
ETL workflows
Example: "Read Postgres records → Transform → Write to MySQL"
AI Agent Workflow Use when:
Building conversational AI
Need AI with tool access
Multi step reasoning tasks
Example: "Chat with AI that can search docs, query database, send emails"
Scheduled Tasks Use when:
Recurring reports or summaries
Periodic data fetching
Maintenance tasks
Example: "Daily: Fetch analytics → Generate report → Email team"
Batch Processing Use when:
Processing large datasets that exceed API batch limits
Need to accumulate results across multiple API calls
Nested loops (e.g., multiple categories × paginated API calls per category)
Example: "Fetch products for 4 markets × 1000 per API call → Aggregate all results"
Common Workflow Components
All patterns share these building blocks:
1. Triggers
Webhook HTTP endpoint (instant)
Schedule Cron based timing (periodic)
Manual Click to execute (testing)
Polling Check for changes (intervals)
2. Data Sources
HTTP Request REST APIs
Database nodes Postgres, MySQL, MongoDB
Service nodes Slack, Google Sheets, etc.
Code Custom JavaScript/Python
3. Transformation
Set Map/transform fields
Code Complex logic
IF/Switch Conditional routing
Merge Combine data streams
4. Outputs
HTTP Request Call APIs
Database Write data
Communication Email, Slack, Discord
Storage Files, cloud storage
5. Error Handling
Error Trigger Catch workflow errors
IF Check for error conditions
Stop and Error Explicit failure
Continue On Fail Per node setting
Workflow Creation Checklist
When building ANY workflow, follow this checklist:
Planning Phase
[ ] Identify the pattern (webhook, API, database, AI, scheduled)
[ ] List required nodes (use search nodes)
[ ] Understand data flow (input → transform → output)
[ ] Plan error handling strategy
Implementation Phase
[ ] Create workflow with appropriate trigger
[ ] Add data source nodes
[ ] Configure authentication/credentials
[ ] Add transformation nodes (Set, Code, IF)
[ ] Add output/action nodes
[ ] Configure error handling
Validation Phase
[ ] Validate each node configuration (validate node)
[ ] Validate complete workflow (validate workflow)
[ ] Test with sample data
[ ] Handle edge cases (empty data, errors)
Deployment Phase
[ ] Review workflow settings (execution order, timeout, error handling)
[ ] Activate workflow using activateWorkflow operation
[ ] Monitor first executions
[ ] Document workflow purpose and data flow
Workflow lifecycle: validate, verify, test before activating
Building the nodes is the start, not the finish. Before a workflow goes live, run it through four gates — and remember the headline rule: validation passing is necessary, not sufficient. A workflow can validate clean and still drop items, pick the wrong Merge input, or post Slack messages as plain text. Clean validation means the shapes are right, not that the logic is.
1. Validate. Run validate workflow on the full JSON during build, or n8n validate workflow({ id }) once the workflow exists on the instance. Fix every error and re validate. This catches schema, node config, expression, and reference errors — the structural layer.
2. Verify the connections. Pull the workflow with n8n get workflow({ id }) and read the connections object directly. Validation confirms connections aren't broken ; it doesn't confirm they're correct . This is where you catch the valid but wrong wiring: a Merge whose useDataOfInput doesn't line up with the connection slot, a Switch fallback that connects to nothing, a fan out branch that was never wired onward, an error output that goes nowhere. (See the n8n Node Configuration skill's NODE FAMILY GOTCHAS.md for the silent ones.)
3. Test. Run n8n test workflow and inspect the output via n8n executions . Confirm the output shape matches what consumers expect, fan outs all produced data, and (for webhook APIs) the status/body/headers are right. Real side effects fire during a test — writes commit, messages send, external APIs are called. If any node has a user visible side effect, confirm with the user before running, or test against safe data first.
4. Activate only after the first three pass — using n8n update partial workflow with the activateWorkflow operation. Don't activate straight off a clean validation; an active workflow that drops data or double sends is worse than one that never started.
Skipping any gate trades a few minutes now for debugging a live, possibly stateful, possibly traffic bearing workflow later. The trade is never worth it.
Data Flow Patterns
Linear Flow
Use when : Simple workflows with single path
Branching Flow
Use when : Different actions based on conditions
Parallel Processing
Use when : Independent operations that can run simultaneously
Loop Pattern
Use when : Processing large datasets in chunks
Error Handler Pattern
Use when : Need separate error handling workflow
Batch Processing Pattern
SplitInBatches Loop
The SplitInBatches node splits a large dataset into smaller chunks for processing. Understanding its outputs is critical:
main[0] = done — fires ONCE after all batches complete
main[1] = each batch — fires per batch (this is the loop body)
Always add a Limit 1 node after the done output.
Choosing batchSize (the cost lever)
A SplitInBatches loop re runs its whole body once per iteration — ~0.8 ms/iteration of engine overhead plus the body's own cost — so total ≈ ⌈items / batchSize⌉ × (overhead + body) . batchSize is a direct speed dial:
Pick the largest batch your real constraint allows (API page size, rate limit, memory). Bigger batches = fewer iterations = less overhead; the body still sees every item.
batchSize: 1 is the expensive extreme — one full engine pass per item. Use it only when you must act on a single item at a time (nested loop control, or an API that takes exactly one id).
If you're looping only to "go over the items" with no external constraint, you usually don't need the loop — a single All Items Code node processes the whole set far cheaper.
Cross Iteration Data
After the loop, $('Node Inside Loop').all() returns ONLY the last batch's items . To accumulate across all iterations, use $getWorkflowStaticData('global') in a Code node inside the loop. See the n8n Code JavaScript skill for the full pattern.
Nested Loops
When processing N categories × M items per category (where an API has a batch limit):
Wiring gotcha : The inner done[0] must connect back to the OUTER loop input, not to the aggregate. The outer done[0] feeds the final aggregate.
API Pagination
For APIs without multi ID filtering, use id from + date windowing for efficient pagination:
Dry Run / Verification Tolerance
When testing with API write nodes disabled (for dry runs), downstream verification nodes receive the request body instead of the response. Make verification tolerant:
Performance on the hot path
When a workflow processes thousands of items with little I/O, its speed is set by how many times n8n crosses a per item / per iteration boundary — each crossing sets up an execution context and copies the items. Four architecture choices dominate:
1. Prefer fewer, fatter All Items nodes over long transform chains. Every node→node hop re copies all items (~0.05 ms/item per hop), so six chained Code/Set nodes cost ~7× one All Items Code node doing the same steps. Consolidate the hot path.
2. Use Code "Run Once for All Items," not "Each Item" — ~0.02 ms/item vs ~0.6 ms/item (≈25–30×). A chain of Each Item Code nodes is the worst case; the per item tax multiplies by node count.
3. Maximize batchSize in SplitInBatches loops (see the Batch Processing pattern above) — iterations are the cost.
4. Don't micro optimize expressions — complexity is free; node and iteration count are what you pay for.
But profile first. Most production workflows are I/O bound — sequential HTTP / DB / Sheets calls (hundreds of ms each) dwarf all of the above. These rules matter when transform work is the floor, or when an anti pattern (Each Item Code, batchSize 1, long per item chains) turns a cheap operation into a slow one. Below a few hundred items, none of it matters. The n8n Code JavaScript skill has the full measured model.
Integration Specific Gotchas
Google Sheets
NEVER use append on sheets with formula columns — it breaks formulas. Use Google Sheets API values.update (PUT) via HTTP Request node with a googleApi credential
Write numbers, not strings for formula dependent columns — string "4.98" breaks ADD() formulas. Use parseFloat() in a Code node
Per item execution trap : Google Sheets nodes execute once per input item. If you need a single bulk write, aggregate items into one in a Code node first
UNFORMATTED VALUE returns numbers , not text like "N/A" — filter explicitly in Code nodes
Google Drive
convertToGoogleDocument: true creates a Google Doc (text) , NOT a Google Sheet — to upload a CSV for download, omit this option entirely
CSV download link format : https://drive.google.com/uc?id={fileId}&export=download — use instead of /view links
Bidirectional Threshold Checking
When comparing values (prices, quantities, metrics), always check both directions:
Common Gotchas
1. Webhook Data Structure
Problem : Can't access webhook payload data
Solution : Data is nested under $json.body
See: n8n Expression Syntax skill
2. Multiple Input Items
Problem : Node processes all input items, but I only want one
Solution : Use "Execute Once" mode or process first item only
3. Authentication Issues
Problem : API calls failing with 401/403
Solution :
Configure credentials properly
Use the "Credentials" section, not parameters
Test credentials before workflow activation
4. Node Execution Order
Problem : Nodes executing in unexpected order
Solution : Check workflow settings → Execution Order
v0: Top to bottom (legacy)
v1