n8n for Workflow Automation: A Complete Guide

You've got a founder-shaped problem: sales calls need to hit the CRM, invoices need to chase themselves, and every SaaS tool you own has a webhook nobody's wired up. Zapier's per-task pricing is punishing you, Make feels like a spreadsheet on fire, and you keep hearing "just use n8n." This post is the honest field guide — what n8n does well, where it hurts, and when you should pick something AI-native instead.
I've shipped n8n workflows to production for solo founders and small ops teams. I still run some. I've also ripped a few out. Here's what I've learned.
What n8n actually is (and what it isn't)
n8n is a self-hostable, node-based workflow automation tool. You drag nodes onto a canvas, connect them, and each node calls an API, transforms data, or branches on a condition. It's the closest open-source cousin to Zapier and Make, with one meaningful difference: you can run it on your own server for the cost of a VPS.
What it isn't: an AI agent platform. n8n has added AI nodes — LangChain integrations, vector stores, chat triggers — but the core execution model is still deterministic, node-to-node flow. If node 3 fails, node 4 doesn't run. That's a feature for reliable pipelines. It's a limitation when you want an agent to reason about which tool to call next.
It also isn't a general-purpose ETL tool. You can move data around, but for anything above ~10k records per run you'll want something built for batch — Airbyte, dbt, or a raw Python job on a schedule.
Use n8n when:
- You have between 3 and ~40 nodes per workflow.
- The logic is mostly IF-THIS-THEN-THAT with light transformation.
- You want to self-host to keep data on your infra or avoid per-task pricing.
- You need a lot of pre-built integrations (n8n ships 400+ nodes).
Pricing: self-hosted vs cloud, honestly
n8n has two commercial tracks: n8n Cloud (they host it, you pay by executions and active workflows) and self-hosted (Community Edition is free under the Sustainable Use License; Enterprise adds SSO, RBAC, and audit logs).
I won't quote current prices — check n8n.io/pricing because the plans shift. What I will say from running both:
| Option | Real monthly cost for a small team | Ops burden |
|---|---|---|
| n8n Cloud (Starter tier) | Predictable low-mid two-digit USD | Zero. It just works. |
| Self-host on a $6 VPS (Hetzner/DigitalOcean) | ~$6-12 + your time | Real. Upgrades, backups, SSL, monitoring. |
| Self-host on Railway/Render | Mid two-digit USD | Low. Managed platform handles infra. |
| Enterprise (self-hosted with support) | Talk to sales | Depends on your team. |
The trap: people self-host to "save money," lose a weekend to a broken upgrade, and end up spending more than a Cloud subscription would've cost. If you don't already run Docker containers in production, use Cloud until you outgrow it. Self-host when you have a compliance reason (HIPAA-adjacent data, EU residency, client contracts) or when your execution volume genuinely makes Cloud expensive.
Setting up n8n in 15 minutes (self-hosted)
Here's the minimum viable production setup. Docker Compose on a small VPS, Postgres for the database (don't use SQLite past prototyping), and Caddy for automatic SSL.
# docker-compose.yml
services:
postgres:
image: postgres:16
restart: always
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: n8n
volumes:
- pgdata:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: always
ports:
- "5678:5678"
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD}
N8N_HOST: n8n.yourdomain.com
N8N_PROTOCOL: https
WEBHOOK_URL: https://n8n.yourdomain.com/
N8N_ENCRYPTION_KEY: ${ENCRYPTION_KEY}
GENERIC_TIMEZONE: America/New_York
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
volumes:
pgdata:
n8n_data:
Two things people forget:
N8N_ENCRYPTION_KEY— generate it once (openssl rand -hex 32) and never change it. If you lose it, every stored credential is unrecoverable.- Back up the Postgres volume, not just the n8n one. Workflows and executions live in Postgres.
Front it with Caddy (three lines gets you HTTPS) or Cloudflare Tunnel if you don't want to open ports.
A real workflow: lead → CRM → Slack → welcome email
Here's the shape of a workflow I've built dozens of times. Someone fills out a Typeform, we enrich the lead, drop it in HubSpot, alert the founder in Slack, and fire a personalized welcome email through Resend.
The n8n version has six nodes:
- Typeform Trigger — webhook fires on submit.
- HTTP Request — call an enrichment API (Clearbit, Apollo, or Hunter).
- Function node — normalize the payload.
- HubSpot node — upsert contact.
- Slack node — post to
#leadschannel. - Resend node (HTTP Request, since there's no native node) — send email.
The Function node is where the real work lives:
// Function node: normalize enriched lead
const raw = $input.first().json;
const enriched = $('HTTP Request').first().json;
return [{
json: {
email: raw.email.toLowerCase().trim(),
firstName: raw.first_name || enriched.person?.firstName || '',
lastName: raw.last_name || enriched.person?.lastName || '',
company: enriched.company?.name || raw.company || 'Unknown',
employeeCount: enriched.company?.metrics?.employees || null,
source: 'typeform-pricing-page',
submittedAt: new Date().toISOString(),
}
}];
Total build time: about 40 minutes if you already have API keys ready. Total monthly cost: pennies in n8n executions, plus whatever the enrichment API charges per lookup.
Where this breaks down: when the "personalized welcome email" needs to actually be personalized. n8n can stuff a first name into a template, but if you want the email to reference what the lead wrote in the "biggest challenge" field and adapt tone based on their industry — you need an LLM call, a prompt, and error handling around a non-deterministic output. That's where the node graph starts to feel wrong.
n8n's real limitations
After running these workflows in production, here's what stops working:
AI is a bolted-on afterthought. The LangChain nodes work, but debugging an agent that decides which tool to call from a canvas is painful. You can't see the reasoning trace inline. Errors in tool calls surface as red nodes, not as "the model chose the wrong tool because the prompt was ambiguous."
Version control is second-class. n8n workflows are JSON. You can export them, commit them, and use the n8n import:workflow CLI. But there's no branch-aware diff in the UI, no PR review flow, and merging two people's edits to the same workflow is a manual JSON conflict.
Testing is manual. You run a workflow, see if it worked, adjust. No unit tests. No mocked triggers. For business-critical automations, this is a real risk — you find out the workflow broke when the founder Slacks you asking why leads stopped landing in HubSpot.
The Function node is where discipline dies. JavaScript inside nodes doesn't get linted, doesn't get typed, doesn't get code-reviewed unless you deliberately export and diff. Every workflow accumulates a pile of ad-hoc transforms that only the original author understands.
Long-running or high-concurrency workflows need queue mode. Default n8n runs executions in the main process. Push enough load and it stalls. You'll need to switch to queue mode with Redis, which is another layer of ops.
n8n vs Zapier vs Make vs AI-native platforms
Here's how I actually pick between the four categories.
| Criterion | n8n | Zapier | Make | AI-native (agent platforms) |
|---|---|---|---|---|
| Best for | Self-hosted deterministic flows | Non-technical users, simple triggers | Visual complex flows, cheaper than Zapier | Non-deterministic AI decisioning |
| Pricing model | Free self-hosted or exec-based cloud | Per-task, expensive at scale | Per-operation, cheaper than Zapier | Usually per-token or per-run |
| Learning curve | Medium (dev-friendly) | Low | Medium-high (complex UI) | Depends on platform |
| AI integration | Bolted-on nodes | Basic AI actions | Basic AI modules | Native, first-class |
| Version control | Manual JSON export | None | None | Varies, often git-native |
| Self-host option | Yes | No | No | Rarely |
| Right when... | You want ownership and don't mind ops | You need it working in 10 minutes | You have complex branching, no dev | Agent needs to reason, not just execute |
The honest read: n8n is the best tool in its category for developers who want ownership. Zapier is the best for non-technical users. Make wins on complex visual branching. But none of them are the right tool when your workflow needs an LLM to make decisions, call tools dynamically, and handle the mess of natural language input.
When to reach for an AI-first platform instead
Signs your n8n workflow is fighting you:
- You have three or more nodes that just call an LLM and parse the response.
- Your Function nodes are 40+ lines of prompt-and-parse logic.
- You're branching on LLM output ("if sentiment is negative, route to human").
- You need the workflow to handle input you can't schema in advance (email bodies, meeting transcripts, PDFs).
- You're building something that looks less like a pipeline and more like an assistant.
At that point, you're forcing an agent-shaped problem into a pipeline-shaped tool. The result is a fragile workflow that breaks every time the LLM output shifts slightly, wrapped in defensive JavaScript nobody wants to maintain.
AI-native platforms — the category includes LangGraph, CrewAI, Vellum, and custom builds on top of Claude or GPT — treat the LLM as the orchestrator, not a node. The workflow becomes: "here's the goal, here are the tools, figure it out." You lose some of n8n's determinism. You gain the ability to handle inputs and decisions that don't fit a flowchart.
The right architecture is usually both. n8n handles the deterministic edges — webhooks in, database writes out, Slack notifications, scheduled jobs. The AI-native piece handles the reasoning in the middle. n8n calls it via HTTP; the agent returns structured output; n8n takes it from there.
How BizFlowAI approaches this
We build hybrid stacks for exactly this reason. Most of our client automations use n8n (or a similar orchestrator) as the reliable spine — webhook triggers, CRM writes, Slack alerts, scheduled polling — and hand off the messy middle to a purpose-built AI agent running on Claude. The agent reads the email, classifies the intent, drafts the reply, and returns structured JSON. n8n takes that JSON and does deterministic things with it.
The result is workflows that ship in days instead of weeks, cost cents per run instead of per-task Zapier bills, and don't collapse the first time a user sends an input the original flowchart didn't anticipate. If you're staring at an n8n canvas with six LLM nodes wired in series, that's usually the signal to rearchitect — and it's the exact shape of problem we help small teams solve.
Bottom line
n8n is a legitimately good tool. If your automation looks like a pipeline — trigger, transform, load, notify — self-host it, own it, and stop paying Zapier's per-task tax. If your automation looks like a decision-maker — read this, understand it, choose the next step — n8n will fight you every time you add an LLM node.
The builder move is knowing which one you have. Most SMB automations are 80% pipeline and 20% reasoning. Use n8n for the 80%. Use an AI-native layer for the 20%. Wire them together with an HTTP call. That's the stack that actually ships.
Work with BizFlowAI
If you'd rather have this built for you, that's what we do: production AI automation for solo founders and small teams — agents, integrations, and document pipelines that actually ship.
Book a free discovery call — 30 minutes, we map the highest-ROI automation in your workflow. No pitch deck, just engineering.
More guides like this on the BizFlowAI blog.
Frequently asked questions
What is n8n and how does it compare to Zapier?
n8n is a self-hostable, node-based workflow automation tool that connects APIs, transforms data, and branches on conditions using a visual canvas. Unlike Zapier, which is cloud-only and charges per task, n8n can run on your own VPS for the cost of the server and ships with 400+ integrations. It's more developer-friendly than Zapier but has a steeper learning curve. Zapier is better for non-technical users who need something working in 10 minutes, while n8n wins on ownership and cost at scale.
Should I self-host n8n or use n8n Cloud?
Use n8n Cloud if you don't already run Docker containers in production — the ops burden of self-hosting (upgrades, backups, SSL, monitoring) often costs more in time than the Cloud subscription saves. Self-host when you have a compliance reason like HIPAA-adjacent data or EU residency requirements, or when your execution volume genuinely makes Cloud expensive. A $6 VPS on Hetzner or DigitalOcean works technically, but managed platforms like Railway reduce the ops load.
How do I set up n8n with Docker Compose in production?
Run n8n in Docker Compose with Postgres (not SQLite) as the database, and put Caddy or Cloudflare Tunnel in front for HTTPS. Generate an N8N_ENCRYPTION_KEY once with `openssl rand -hex 32` and never change it — losing it makes all stored credentials unrecoverable. Back up the Postgres volume, not just the n8n data volume, because workflows and executions live in Postgres. A minimum viable setup takes about 15 minutes.
What are the biggest limitations of n8n?
n8n's main limitations are that AI is bolted on rather than native (debugging agents on a canvas is painful), version control is second-class (workflows are JSON with no PR review flow), and there's no built-in testing or mocked triggers. The Function node lets JavaScript accumulate without linting, typing, or review. High-concurrency workflows also require switching to queue mode with Redis, adding ops complexity. It's best suited for deterministic flows with 3-40 nodes, not AI agent reasoning or high-volume ETL.
When should I use n8n instead of an AI agent platform?
Use n8n when your logic is mostly IF-THIS-THEN-THAT with light transformation and deterministic node-to-node flow — for example, moving a form submission through enrichment, CRM upsert, Slack alert, and email. Use an AI-native agent platform when the workflow requires non-deterministic reasoning, like an LLM deciding which tool to call or personalizing output based on unstructured input. n8n can call an LLM, but the node graph feels wrong once reasoning and error handling around non-deterministic output dominate the flow.