Generated banner for N8n Workflow Patterns
Generated logo for N8n Workflow Patterns

N8n Workflow Patterns

Romuald CzlonkowskiCommunityCreated by Romuald Czlonkowski

  • Skill
  • Guidelines
  • Automation and integrations
  • MIT
  • Medium risk

From the author

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 processing, or scheduled tasks. Always consult this skill when the user asks to create, build, or design an n8n workflow, automate a process, or connect services — even if they don't explicitly mention 'patterns'. Covers webhook, API, database, AI, batch processing, and scheduled automation architectures. Also use when optimizing a slow workflow or speeding up large-item-count processing (node count, batchSize, all-items vs per-item).
— the description by Romuald Czlonkowski

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured framework for designing n8n workflows based on six core architectural patterns: Webhook Processing, HTTP API Integration, Database Operations, AI Agent Workflows, Scheduled Tasks, and Batch Processing. It offers a comprehensive checklist for the entire workflow lifecycle, from planning and implementation to validation and deployment. The skill emphasizes native node usage, effective error handling, and performance considerations for processing data, ensuring workflows are robust, maintainable, and correctly structured.

What it does

  • Defines six core architectural patterns for n8n automation.
  • Provides a step-by-step workflow creation and validation checklist.
  • Offers guidance on choosing the right trigger and transformation nodes.
  • Details strategies for batch processing and handling API rate limits.
  • Outlines best practices for error handling and workflow monitoring.
  • Includes specific patterns for AI agent integration and database synchronization.

When to use it

  • When designing the architecture for a new n8n automation.
  • When choosing between different workflow patterns like webhooks or scheduled tasks.
  • When optimizing the structure of an existing, complex workflow.
  • When troubleshooting data flow or performance issues in a workflow.
  • When preparing a workflow for production deployment.

Advantages

  • Standardizes workflow design using proven architectural patterns.
  • Reduces development time by providing clear implementation paths.
  • Improves workflow reliability through structured validation and error handling.
  • Helps avoid common pitfalls in node configuration and data mapping.
  • Provides clear guidance on when to use specific nodes versus custom code.

Usage examples

“How should I structure a workflow that receives data from a webhook and updates a database?”
The agent will recommend the Webhook Processing pattern, detailing the sequence of Webhook trigger, validation, transformation, and database write nodes.
“I need to process thousands of records from an API without hitting rate limits. What pattern should I use?”
The agent will suggest the Batch Processing pattern, explaining how to use the SplitInBatches node to chunk data and manage API calls effectively.
“What is the best way to handle errors in my n8n workflow?”
The agent will outline the Error Handler pattern, including the use of Error Triggers and the 'Continue On Fail' node setting.
“How do I build an AI agent that can query my database?”
The agent will provide the AI Agent Workflow pattern, including the setup for the AI Agent node, memory, and database tools.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/czlonkowski/n8n-workflow-patterns/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip n8n-workflow-patterns.zip -d .agents/skills

Documentation by Romuald Czlonkowski

n8n Workflow Patterns

Proven architectural patterns for building n8n workflows.


The 6 Core Patterns

Based on analysis of real workflow usage:

  1. Webhook Processing (Most Common)

    • Receive HTTP requests → Process → Output

    • Pattern: Webhook → Validate → Transform → Respond/Notify

  2. HTTP API Integration

    • Fetch from REST APIs → Transform → Store/Use

    • Pattern: Trigger → HTTP Request → Transform → Action → Error Handler

  3. Database Operations

    • Read/Write/Sync database data

    • Pattern: Schedule → Query → Transform → Write → Verify

  4. AI Agent Workflow

    • AI agents with tools and memory

    • Pattern: Trigger → AI Agent (Model + Tools + Memory) → Output

  5. Scheduled Tasks

    • 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.

  • Extract From File - CSV / XLSX / PDF from a downloaded or uploaded file

3. Transformation (native first)
  • Filter / IF / Switch - Drop items, route

  • Edit Fields (Set) - Named steps: constant items, payload objects, error and return items

  • Summarize / Aggregate / Split Out - Group and total, collect into an array, explode an array

  • Merge / Compare Datasets - Join two lists, diff them for a sync

  • Remove Duplicates / Sort / Limit - Dedupe (also across runs), top-N

  • Date & Time, XML, HTML, Crypto - Dates, markup, hashes and signatures

  • Code - Only the closed list (loops or recursion no node expresses, state across runs, parsing no node handles), with a Why Code: note

The job-to-node table in using-n8n-mcp-skills maps jobs to these nodes; configs are in n8n-node-configuration → NATIVE_NODES.md. Reading a filtered slice of a nested API response for one field? A single {{ $jmespath($json, "…") }} in that field does it without extra nodes (quoting rules in n8n-expression-syntax).

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 (native first: Filter, IF, Summarize, Merge…; Code only with a Why Code: note)

  • [ ] 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
Trigger → Transform → Action → End

Use when: Simple workflows with single path

Branching Flow
Trigger → IF → [True Path]
             └→ [False Path]

Use when: Different actions based on conditions

Parallel Processing
Trigger → [Branch 1] → Merge
       └→ [Branch 2] ↗

Use when: Independent operations that can run simultaneously

Loop Pattern
Trigger → Split in Batches → Process → Loop (until done)

Use when: Processing large datasets in chunks

Error Handler Pattern
Main Flow → [Success Path]
         └→ [Error Trigger → Error Handler]

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)

Prepare Items → SplitInBatches → [main[1]: Process Batch] → (loops back)
                                  [main[0]: Done] → Limit 1 → Aggregate

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 don't need the loop: connect the source to the consumer. Per-item execution handles it, and native transform nodes process all items in one call.

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):

Define Categories (N items)
  → Outer Loop (SplitInBatches, batchSize=1)
    → Prepare category data
    → Inner Loop (SplitInBatches, batchSize=1000)
      → API Call → Verify → (loops back to Inner Loop via main[1])
    → Inner done[0] → Rate Limit Delay → back to Outer Loop
  → Outer done[0] → Limit 1 → Final Aggregate

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

Paging through one endpoint is HTTP Request's pagination option, not a loop (page-number, offset, cursor and next-URL APIs, with a page cap — see n8n-node-configuration → NATIVE_NODES.md). The loop below is for sweeps the option can't express, such as an API without multi-ID filtering that you walk with id_from + date windows, each window its own query:

Schedule → Set Date Window → Fetch Page → Process
  → IF has more? → [true] Update id_from → Fetch Page (loop)
                  → [false] → Aggregate → Output
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:

// In verification Code node
const body = $input.first().json;
const looksLikeRequest = body.method && body.parameters && !body.status;
if (looksLikeRequest) {
  return [{ json: { status: 'SKIPPED', message: 'Upstream disabled for testing' }}];
}
// Normal response verification below...

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. Consolidating a hot chain into one Code node is an exception, not a default. Every node→node hop re-copies all items, so on a measured hot path — thousands of items per run, transform work rather than I/O dominating — one All-Items Code node can beat a long chain. That is the closed list's "heavy all-items work" case: record it in the node's Why Code: note. Below that, native nodes win on readability.

  2. If Code stays, use "Run Once for All Items," not "Each Item." Each Item pays a full sandbox per item; a chain of Each-Item Code nodes is the worst case, because 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. Convert in the column's expression: {{ $json.price.toNumber() }} or {{ parseFloat($json.price) }}

  • Per-item execution trap: Google Sheets nodes execute once per input item. If you need a single bulk write, collect the rows into one item with an Aggregate node first

  • UNFORMATTED_VALUE returns numbers, not text like "N/A" — filter explicitly with a Filter node

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:

// ❌ Only catches increases
if (diff > threshold) { flag(); }

// ✅ Catches both spikes AND crashes — both are data-quality signals
if (Math.abs(diff) > threshold) { flag(); }

Common Gotchas

1. Webhook Data Structure

Problem: Can't access webhook payload data

Solution: Data is nested under $json.body

❌ {{$json.email}}
✅ {{$json.body.email}}

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

{{$json[0].field}}  // 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: Connection-based (recommended)

5. Expression Errors

Problem: Expressions showing as literal text

Solution: Use {{}} around expressions

  • See n8n Expression Syntax skill for details


Integration with Other Skills

These skills work together with Workflow Patterns:

n8n MCP Tools Expert - Use to:

  • Find nodes for your pattern (search_nodes)

  • Understand node operations (get_node)

  • Create workflows (n8n_create_workflow)

  • Deploy templates (n8n_deploy_template)

  • Use tools_documentation({topic: "ai_agents_guide", depth: "full"}) for AI pattern guidance

  • Manage data tables with n8n_manage_datatable

  • Organize workflows into folders with n8n_manage_folders

n8n Expression Syntax - Use to:

  • Write expressions in transformation nodes

  • Access webhook data correctly ({{$json.body.field}})

  • Reference previous nodes ({{$node["Node Name"].json.field}})

n8n Node Configuration - Use to:

  • Configure specific operations for pattern nodes

  • Understand node-specific requirements

n8n Validation Expert - Use to:

  • Validate workflow structure

  • Fix validation errors

  • Ensure workflow correctness before deployment


Pattern Statistics

Common workflow patterns:

Most Common Triggers:

  1. Webhook - 35%

  2. Schedule (periodic tasks) - 28%

  3. Manual (testing/admin) - 22%

  4. Service triggers (Slack, email, etc.) - 15%

Most Common Transformations:

  1. Set (field mapping) - 68%

  2. Code (custom logic) - 42%

  3. IF (conditional routing) - 38%

  4. Switch (multi-condition) - 18%

Most Common Outputs:

  1. HTTP Request (APIs) - 45%

  2. Slack - 32%

  3. Database writes - 28%

  4. Email - 24%

Average Workflow Complexity:

  • Simple (3-5 nodes): 42%

  • Medium (6-10 nodes): 38%

  • Complex (11+ nodes): 20%


Quick Start Examples

Example 1: Simple Webhook → Slack
1. Webhook (path: "form-submit", POST)
2. Slack (post message to #notifications; the text maps $json.body fields with expressions)
Example 2: Scheduled Report
1. Schedule (daily at 9 AM)
2. HTTP Request (fetch analytics)
3. Summarize (totals per group)
4. Email (send formatted report)
5. Error Trigger → Slack (notify on failure)
Example 3: Database Sync
1. Schedule (every 15 minutes)
2. Postgres (query new records)
3. IF (check if records exist)
4. MySQL (insert records)
5. Postgres (update sync timestamp)
Example 4: AI Assistant
1. Webhook (receive chat message)
2. AI Agent
   ├─ OpenAI Chat Model (ai_languageModel)
   ├─ HTTP Request Tool (ai_tool)
   ├─ Database Tool (ai_tool)
   └─ Window Buffer Memory (ai_memory)
3. Webhook Response (send AI reply)
Example 5: API Integration
1. Manual Trigger (for testing)
2. HTTP Request (GET /api/users; pagination option if the API pages)
3. Postgres (upsert users; map the fields in the node's column slots)

No loop and no Set: Postgres processes every item, and the column slots take the mapping expressions.


Detailed Pattern Files

For comprehensive guidance on each pattern:


Real Template Examples

From n8n template library:

Template #2947: Weather to Slack

  • Pattern: Scheduled Task

  • Nodes: Schedule → HTTP Request (weather API) → Set → Slack

  • Complexity: Simple (4 nodes)

Webhook Processing: Most common pattern

  • Most common: Form submissions, payment webhooks, chat integrations

HTTP API: Common pattern

  • Most common: Data fetching, third-party integrations

Database Operations: Common pattern

  • Most common: ETL, data sync, backup workflows

AI Agents: Growing in usage

  • Most common: Chatbots, content generation, data analysis

Use search_templates and get_template from n8n-mcp tools to find examples!


Best Practices

✅ Do
  • Start with the simplest pattern that solves your problem

  • Plan your workflow structure before building

  • Use error handling on all workflows

  • Test with sample data before activation

  • Follow the workflow creation checklist

  • Use descriptive node names

  • Document complex workflows (notes field)

  • Monitor workflow executions after deployment

❌ Don't
  • Build workflows in one shot (iterate! avg 56s between edits)

  • Skip validation before activation

  • Ignore error scenarios

  • Use complex patterns when simple ones suffice

  • Hardcode credentials in parameters

  • Forget to handle empty data cases

  • Mix multiple patterns without clear boundaries

  • Deploy without testing


Summary

Key Points:

  1. 6 core patterns cover 90%+ of workflow use cases

  2. Webhook processing is the most common pattern

  3. Use the workflow creation checklist for every workflow

  4. Plan pattern → Select nodes → Build → Validate → Deploy

  5. Integrate with other skills for complete workflow development

Next Steps:

  1. Identify your use case pattern

  2. Read the detailed pattern file

  3. Use n8n MCP Tools Expert to find nodes

  4. Follow the workflow creation checklist

  5. Use n8n Validation Expert to validate

Related Skills:

  • n8n MCP Tools Expert - Find and configure nodes

  • n8n Expression Syntax - Write expressions correctly

  • n8n Validation Expert - Validate and fix errors

  • n8n Node Configuration - Configure specific operations

Files

scheduled_tasks.md

Scheduled Tasks Pattern

Use Case: Recurring automation workflows that run automatically on a schedule.


Pattern Structure

Schedule Trigger → [Fetch Data] → [Process] → [Deliver] → [Log/Notify]

Key Characteristic: Time-based automated execution


Core Components

1. Schedule Trigger

Purpose: Execute workflow at specified times

Modes:

  • Interval - Every X minutes/hours/days

  • Cron - Specific times (advanced)

  • Days & Hours - Simple recurring schedule

2. Data Source

Common sources:

  • HTTP Request (APIs)

  • Database queries

  • File reads

  • Service-specific nodes

3. Processing

Typical operations:

  • Filter/transform data

  • Aggregate statistics

  • Generate reports

  • Check conditions

4. Delivery

Output channels:

  • Email

  • Slack/Discord/Teams

  • File storage

  • Database writes

5. Logging

Purpose: Track execution history

Methods:

  • Database log entries

  • File append

  • Monitoring service


Schedule Configuration

Interval Mode

Best for: Simple recurring tasks

Examples:

// Every 15 minutes
{
  mode: "interval",
  interval: 15,
  unit: "minutes"
}

// Every 2 hours
{
  mode: "interval",
  interval: 2,
  unit: "hours"
}

// Every day at midnight
{
  mode: "interval",
  interval: 1,
  unit: "days"
}
Days & Hours Mode

Best for: Specific days and times

Examples:

// Weekdays at 9 AM
{
  mode: "daysAndHours",
  days: ["monday", "tuesday", "wednesday", "thursday", "friday"],
  hour: 9,
  minute: 0
}

// Every Monday at 6 PM
{
  mode: "daysAndHours",
  days: ["monday"],
  hour: 18,
  minute: 0
}
Timezone Gotcha (applies to all modes)

triggerAtHour / hour values use the instance timezone, not UTC. n8n resolves it from the GENERIC_TIMEZONE env var (or the workflow's timezone setting); when neither is set, it falls back to the host system timezone. A trigger set to hour 21 on a server in America/Edmonton fires at 9 PM MST, not 21:00 UTC. Always confirm the instance timezone before scheduling, or set the workflow timezone explicitly.

Cron Mode (Advanced)

Best for: Complex schedules

Examples:

// Every weekday at 9 AM
{
  mode: "cron",
  expression: "0 9 * * 1-5"
}

// First day of every month at midnight
{
  mode: "cron",
  expression: "0 0 1 * *"
}

// Every 15 minutes during business hours (9 AM - 5 PM) on weekdays
{
  mode: "cron",
  expression: "*/15 9-17 * * 1-5"
}

Cron format: minute hour day month weekday

  • * = any value

  • */15 = every 15 units

  • 1-5 = range (Monday-Friday)

  • 1,15 = specific values

Cron examples:

0 */6 * * *      Every 6 hours
0 9,17 * * *     At 9 AM and 5 PM daily
0 0 * * 0        Every Sunday at midnight
*/30 * * * *     Every 30 minutes
0 0 1,15 * *     1st and 15th of each month

Common Use Cases

1. Daily Reports

Flow: Schedule → Fetch data → Aggregate → Format → Email

Example (Sales report):

1. Schedule (daily at 9 AM)

2. Postgres (query yesterday's sales)
   SELECT date, SUM(amount) as total, COUNT(*) as orders
   FROM orders
   WHERE date = CURRENT_DATE - INTERVAL '1 day'
   GROUP BY date

3. Email (send to [email protected])
   Subject: Daily Sales Report - {{ $json.date }}
   Body: HTML built with expressions, e.g. average order value {{ ($json.total / $json.orders).toFixed(2) }}

4. Slack (post summary to #sales)

The query already returns the totals, so no transform node is needed. For a day-over-day comparison, return both days from the same SQL (or Summarize over two days' rows) rather than computing it in Code.

2. Data Synchronization

Flow: Schedule → Fetch from source → Transform → Write to target

Example (CRM to data warehouse sync):

1. Schedule (every hour)

2. Postgres (get last sync time)
   SELECT MAX(synced_at) AS last_sync FROM sync_log

3. HTTP Request (fetch new CRM contacts since last sync)
   GET /api/contacts?updated_since={{$json.last_sync}}

4. IF (check if new records exist)

5. Postgres (warehouse - INSERT new contacts; map CRM fields to warehouse columns in the node's column slots)

7. Postgres (UPDATE sync_log SET synced_at = NOW())

8. IF (error occurred)
   └─ Slack (alert #data-team)
3. Monitoring & Health Checks

Flow: Schedule → Check endpoints → Alert if down

Example (Website uptime monitor):

1. Schedule (every 5 minutes)

2. HTTP Request (GET https://example.com/health)
   - timeout: 10 seconds
   - continueOnFail: true

3. IF (status !== 200 OR response_time > 2000ms)

4. Redis (check alert cooldown - don't spam)
   - Key: alert:website_down
   - TTL: 30 minutes

5. IF (no recent alert sent)

6. [Alert Actions]
   ├─ Slack (notify #ops-team)
   ├─ PagerDuty (create incident)
   ├─ Email ([email protected])
   └─ Redis (set alert cooldown)

7. Postgres (log uptime check result)
4. Cleanup & Maintenance

Flow: Schedule → Find old data → Archive/Delete → Report

Example (Database cleanup):

1. Schedule (weekly on Sunday at 2 AM)

2. Postgres (find old records)
   SELECT * FROM logs
   WHERE created_at < NOW() - INTERVAL '90 days'
   LIMIT 10000

3. IF (records exist)

4. Convert To File (operation toJson: all rows into one archive file)

5. Google Drive (upload archive file)
   - Filename: logs_archive_{{ $now.format('yyyy-MM-dd') }}.json

6. Postgres (DELETE archived records)
   DELETE FROM logs
   WHERE id IN ({{$json.archived_ids}})

7. Slack (report: "Archived X records, deleted Y records")
5. Data Enrichment

Flow: Schedule → Find incomplete records → Enrich → Update

Example (Enrich contacts with company data):

1. Schedule (nightly at 3 AM)

2. Postgres (find contacts without company data)
   SELECT id, email, domain FROM contacts
   WHERE company_name IS NULL
   AND created_at > NOW() - INTERVAL '7 days'
   LIMIT 100

3. Loop Over Items (10 contacts per batch)

4. Clearbit (Company → Enrich; domain = {{ $json.email.extractDomain() }})

5. Postgres (UPDATE contacts with company data; map the Clearbit fields in the column slots)

6. Wait (1 second - rate limiting)

7. Loop (back to step 4 until all batches processed)

9. Email (summary: "Enriched X contacts")
6. Backup Automation

Flow: Schedule → Export data → Compress → Store → Verify

Example (Database backup):

1. Schedule (daily at 2 AM)

2. Execute Command (pg_dump -h db.example.com mydb | gzip > /backups/backup.sql.gz)
   - Self-hosted only, and blocked by default: the instance must re-enable the node (see n8n-self-hosting SECURITY.md).
     A Code node can't do this either: child_process is not available in the sandbox.
   - Often better outside n8n: a cron job or the database's own backup tool, with n8n only checking the result.

3. Read/Write Files from Disk (read /backups/backup.sql.gz as binary)
   - For a file that isn't compressed yet, the Compression node gzips it.

4. AWS S3 (upload compressed backup)
   - Bucket: backups
   - Key: db/backup-{{$now.format('YYYY-MM-DD')}}.sql.gz

5. AWS S3 (list old backups)
   - Keep last 30 days only

6. AWS S3 (delete old backups)

7. IF (error occurred)
   ├─ PagerDuty (critical alert)
   └─ Email (backup failed!)
   ELSE
   └─ Slack (#devops: "✅ Backup completed")
7. Content Publishing

Flow: Schedule → Fetch content → Format → Publish

Example (Automated social media posts):

1. Schedule (every 3 hours during business hours)
   - Cron: 0 9,12,15,18 * * 1-5

2. Google Sheets (read content queue)
   - Sheet: "Scheduled Posts"
   - Filter: status=pending AND publish_time <= NOW()

3. IF (posts available)

4. HTTP Request (shorten URLs in post)

5. HTTP Request (POST to Twitter API)

6. HTTP Request (POST to LinkedIn API)

7. Google Sheets (update status=published)

8. Slack (notify #marketing: "Posted: {{$json.title}}")

Timezone Considerations

Set Workflow Timezone
// In workflow settings
{
  timezone: "America/New_York"  // EST/EDT
}
Common Timezones
America/New_York    - Eastern (US)
America/Chicago     - Central (US)
America/Denver      - Mountain (US)
America/Los_Angeles - Pacific (US)
Europe/London       - GMT/BST
Europe/Paris        - CET/CEST
Asia/Tokyo          - JST
Australia/Sydney    - AEDT
UTC                 - Universal Time
Handle Daylight Saving

Best practice: Use timezone-aware scheduling

// ❌ Bad: UTC schedule for "9 AM local"
// Will be off by 1 hour during DST transitions

// ✅ Good: Set workflow timezone
{
  timezone: "America/New_York",
  schedule: {
    mode: "daysAndHours",
    hour: 9  // Always 9 AM Eastern, regardless of DST
  }
}

Error Handling

Pattern 1: Error Trigger Workflow

Main workflow: Normal execution Error workflow: Alerts and recovery

Main:

Schedule → Fetch → Process → Deliver

Error:

Error Trigger (for main workflow)
  ├─→ Slack (#ops-team: "❌ Scheduled job failed"; details from the trigger payload with expressions)
  ├─→ Email (admin alert)
  └─→ Postgres (log error for analysis)
Pattern 2: Retry with Backoff
Schedule → HTTP Request (continueOnFail: true)
  → IF (error)
    ├─ Wait (5 minutes)
    ├─ HTTP Request (retry 1)
    └─ IF (still error)
      ├─ Wait (15 minutes)
      ├─ HTTP Request (retry 2)
      └─ IF (still error)
        └─ Alert admin
Pattern 3: Partial Failure Handling
Schedule → Process (onError: continueErrorOutput)
  ├─ success output → Summarize (count) ─┐
  └─ error output   → Summarize (count) ─┴→ Merge (combine by position) → Report:
       "✅ Processed: 95/100"
       "❌ Failed: 5/100"

Performance Optimization

1. Batch Processing

For large datasets:

Schedule → Query (LIMIT 10000)
  → Split In Batches (100 items)
  → Process batch
  → Loop
2. Parallel Processing

When operations are independent:

Schedule
  ├─ [Branch 1: Update DB]
  ├─ [Branch 2: Send emails]
  └─ [Branch 3: Generate report]
  → Merge (wait for all) → Final notification
3. Skip if Already Running

Prevent overlapping executions:

Schedule → Redis (check lock)
  → IF (lock exists)
    └─ End (skip this execution)
  → ELSE
    ├─ Redis (set lock, TTL 30 min)
    ├─ [Execute workflow]
    └─ Redis (delete lock)
4. Early Exit on No Data

Don't waste time if nothing to process:

Schedule → Query (check if work exists)
  → IF (no results)
    └─ End workflow (exit early)
  → ELSE
    └─ Process data

Monitoring & Logging

Pattern 1: Execution Log Table
CREATE TABLE workflow_executions (
  id SERIAL PRIMARY KEY,
  workflow_name VARCHAR(255),
  started_at TIMESTAMP,
  completed_at TIMESTAMP,
  status VARCHAR(50),
  records_processed INT,
  error_message TEXT
);

Log execution:

Schedule
  → Set (record start)
  → [Workflow logic]
  → Postgres (INSERT execution log)
Pattern 2: Metrics Collection
Schedule → [Execute]
  → Summarize (records processed, successes)
  → HTTP Request (send to monitoring system; duration = {{ $now.diffTo($('Record start').item.json.started_at, 'seconds') }})
    - Datadog, Prometheus, etc.
Pattern 3: Summary Notifications

Daily/weekly execution summaries:

Schedule (daily at 6 PM) → Query execution logs
  → Summarize (count executions, split by status)
  → Email (summary report)
    "Today's Workflow Executions:
     - 24/24 successful
     - 0 failures
     - Avg duration: 2.3 min"

Testing Scheduled Workflows

1. Use Manual Trigger for Testing

Development pattern:

Manual Trigger (for testing)
  → [Same workflow logic]
  → [Outputs]

// Once tested, replace with Schedule Trigger
2. Test with Different Times

Pin a constant item instead of the trigger: an Edit Fields node with currentTime = 2024-01-15T09:00:00Z, and downstream expressions read $json.currentTime instead of $now while testing.

3. Dry Run Mode
Schedule → Set (dryRun: true)
  → IF (dryRun)
    └─ Log what would happen (don't execute)
  → ELSE
    └─ Execute normally
4. Shorter Interval for Testing
// Testing: every 1 minute
{
  mode: "interval",
  interval: 1,
  unit: "minutes"
}

// Production: every 1 hour
{
  mode: "interval",
  interval: 1,
  unit: "hours"
}

Common Gotchas

1. ❌ Wrong: Ignoring timezone
Schedule (9 AM)  // 9 AM in which timezone?
✅ Correct: Set workflow timezone
// Workflow settings
{
  timezone: "America/New_York"
}
2. ❌ Wrong: Overlapping executions
Schedule (every 5 min) → Long-running task (10 min)
// Two executions running simultaneously!
✅ Correct: Add execution lock
Schedule → Redis (check lock)
  → IF (locked) → Skip
  → ELSE → Execute
3. ❌ Wrong: No error handling
Schedule → API call → Process (fails silently)
✅ Correct: Add error workflow
Main: Schedule → Execute
Error: Error Trigger → Alert
4. ❌ Wrong: Processing all data at once
Schedule → SELECT 1000000 records → Process (OOM)
✅ Correct: Batch processing
Schedule → SELECT with pagination → Split In Batches → Process
5. ❌ Wrong: Hardcoded dates
query: "SELECT * FROM orders WHERE date = '2024-01-15'"
✅ Correct: Dynamic dates
query: "SELECT * FROM orders WHERE date = CURRENT_DATE - INTERVAL '1 day'"

Real Template Examples

From n8n template library:

Template #2947 (Weather to Slack):

Schedule (daily 8 AM)
  → HTTP Request (weather API)
  → Set (format message)
  → Slack (post to #general)

Daily backup:

Schedule (nightly 2 AM)
  → Postgres (export data)
  → Google Drive (upload)
  → Email (confirmation)

Monitoring:

Schedule (every 5 min)
  → HTTP Request (health check)
  → IF (down) → PagerDuty alert

Use search_templates({query: "schedule"}) to find more!


Checklist for Scheduled Workflows

Planning
  • [ ] Define schedule frequency (interval, cron, days & hours)

  • [ ] Set workflow timezone

  • [ ] Estimate execution duration

  • [ ] Plan for failures and retries

  • [ ] Consider timezone and DST

Implementation
  • [ ] Configure Schedule Trigger

  • [ ] Set workflow timezone in settings

  • [ ] Add early exit for no-op cases

  • [ ] Implement batch processing for large data

  • [ ] Add execution logging

Error Handling
  • [ ] Create Error Trigger workflow

  • [ ] Implement retry logic

  • [ ] Add alert notifications

  • [ ] Log errors for analysis

  • [ ] Handle partial failures gracefully

Monitoring
  • [ ] Log each execution (start, end, status)

  • [ ] Track metrics (duration, records, success rate)

  • [ ] Set up daily/weekly summaries

  • [ ] Alert on consecutive failures

  • [ ] Monitor resource usage

Testing
  • [ ] Test with Manual Trigger first

  • [ ] Verify timezone behavior

  • [ ] Test error scenarios

  • [ ] Check for overlapping executions

  • [ ] Validate output quality

Deployment
  • [ ] Document workflow purpose

  • [ ] Set up monitoring

  • [ ] Configure alerts

  • [ ] Activate workflow in n8n UI ⚠️ Manual activation required (API/MCP cannot activate)

  • [ ] Test in production (short interval first)

  • [ ] Monitor first few executions


Advanced Patterns

Dynamic Scheduling

Change schedule based on conditions:

Schedule (check every hour)
  → IF ({{ $now.weekday <= 5 && $now.hour >= 9 && $now.hour < 17 }})
    └─ Execute workflow
  → ELSE
    └─ Skip
Dependent Schedules

Chain workflows:

Workflow A (daily 2 AM): Data sync
  → On completion → Trigger Workflow B

Workflow B: Generate report (depends on fresh data)
Conditional Execution

Skip based on external factors:

Schedule → HTTP Request (check feature flag)
  → IF (feature enabled)
    └─ Execute
  → ELSE
    └─ Skip

Summary

Key Points:

  1. Set workflow timezone explicitly

  2. Batch processing for large datasets

  3. Error handling is critical (Error Trigger + retries)

  4. Prevent overlaps with execution locks

  5. Monitor and log all executions

Pattern: Schedule → Fetch → Process → Deliver → Log

Schedule Modes:

  • Interval: Simple recurring (every X minutes/hours)

  • Days & Hours: Specific days and times

  • Cron: Advanced complex schedules

Related:

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Node.js

Security

What our scanner noticed· Medium risk

  • Possible data-exfiltration endpoints

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Romuald Czlonkowski
Publisher
Romuald Czlonkowski (Community)
Source
czlonkowski/n8n-skills · skills/n8n-workflow-patterns · commit e037563
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Romuald Czlonkowski.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download n8n-workflow-patterns.zip