Skip to main content
automationMarch 11, 202614 min read

n8n vs Make.com vs Custom Code: When to Use What

A practical comparison of n8n, Make.com, and custom code for business automation. Based on 50+ automation projects across startups and SMBs.

Loic Bachellerie

Senior Product Engineer

After building 50+ automations, here's when I reach for each tool - and when I don't.

Every week someone asks me: "Should I use n8n, Make.com, or just write code for this?" The honest answer is that each one wins in specific situations, and choosing wrong costs you time, money, or both. I've made all three mistakes. This guide is what I wish I had before I started.

I'll walk through real scenarios, cost structures, and the exact mental framework I use to pick the right tool in under five minutes.

Quick Verdict

If you're in a hurry:

  • Make.com - visual thinkers, marketing teams, 1-100 scenarios with moderate complexity, budget under $50/month
  • n8n - technical founders, complex logic, data privacy concerns, high volume, long-term cost efficiency
  • Custom code - unique logic that no platform supports, maximum performance requirements, or when the automation is core to your product

Now let's go deeper.

Feature Comparison

Featuren8nMake.comCustom Code
Visual builderYesYes (better)No
Custom JS/PythonFull supportLimitedNative
Error handlingAdvancedBasicFull control
SchedulingBuilt-inBuilt-inYour infrastructure
AI/LLM nodesBuilt-inVia HTTPYou build it
Self-hostingYes (open source)NoYes
DebuggingGoodExcellentYour tools
Version controlJSON exportJSON exportGit
Team collaborationPaid plansPaid plansGit-native
Community integrations400+ nodes1,000+ appsAny API

Make.com has more pre-built app connectors. n8n has better code flexibility. Custom code has none of the limitations and all of the complexity.

Pricing Comparison

Pricing models across these three options are fundamentally different, which makes direct comparison tricky.

n8n Pricing

PlanCostExecutions
Self-hosted$5-10/mo (server only)Unlimited
Cloud Starter$0/mo5K executions
Cloud Pro$20/moUnlimited
Cloud EnterpriseCustomCustom

Self-hosting n8n on a $5 DigitalOcean droplet gives you unlimited executions with full data control. That is the real value proposition.

Make.com Pricing

PlanCostOperations/month
Free$01,000
Core$10.59/mo10,000
Pro$18.82/mo10,000 + more features
Teams$34.12/mo10,000 (per seat)
EnterpriseCustomCustom

Make.com charges per operation, not per scenario run. A single scenario with 10 modules costs 10 operations every time it runs. This adds up fast at volume.

Custom Code Pricing

Custom code has no platform cost - but it has real costs:

  • Development time (your time or a contractor)
  • Hosting infrastructure ($5-50/month depending on load)
  • Maintenance and updates (ongoing)
  • Monitoring and alerting (tools like Sentry, Datadog)

For a simple automation that runs once a day, custom code might cost $0/month to run but 8 hours to build. For something complex that runs thousands of times per day, it might be the cheapest option per execution.

Cost at Scale

Monthly Volumen8n Self-HostedMake.comCustom Code (hosting)
1K runs$5$10.59$5-15
10K runs$5$18.82$5-15
100K runs$10$55+$10-30
1M runs$20$200+$20-80

Above 10K monthly runs, n8n self-hosted consistently wins on pure cost.

Cost at Scale

Monthly cost comparison at 100K automation runs

n8n
Self-hosted$10/mo
Cloud$20/mo

Unlimited executions on self-hosted

Make.com
100K ops$55+/mo
1M ops$200+/mo

Cost scales with operation count

Custom Code
Hosting$10-30/mo
Build costHigh upfront

Cheapest per-run at high volume

When to Use n8n

n8n is my default choice for technical clients who need serious automation without the Zapier tax. Here is when it earns that position.

You Have Complex Logic

n8n's Code node gives you full JavaScript and Python inside your workflows. When a client needed to parse webhook payloads, run custom business logic, and make conditional API calls based on database lookups, all in one flow, n8n handled it cleanly. Make.com would have required workarounds or multiple disconnected scenarios.

You Care About Data Privacy

A healthcare client needed to automate appointment reminders without patient data leaving their infrastructure. Self-hosted n8n running inside their VPC solved it. There is no Make.com equivalent for that requirement.

Your Volume Is High

At 50,000+ automation runs per month, Make.com pricing gets painful fast. Self-hosted n8n at that volume costs the same as 1,000 runs: whatever your server costs.

You Want AI Deeply Integrated

n8n has native LLM nodes. You can build multi-step AI agents - call an LLM, evaluate the output with another node, branch based on the result, call a tool, and loop - without any HTTP gymnastics. This is increasingly where complex automations live.

Real n8n Examples from Client Work

Example 1: Lead scoring pipeline. A B2B SaaS company had 300+ inbound leads per week. Built an n8n workflow: webhook receives form submission, Code node runs enrichment logic against Clearbit API, OpenAI node scores the lead 0-100 based on ICP criteria, Switch node routes to Slack for hot leads and HubSpot for all leads. Cut manual qualification time from 4 hours/day to zero.

Example 2: E-commerce order sync. A Shopify store needed real-time syncing across three warehouses with custom priority logic. The business rules were too complex for Make.com's routing. n8n's Code nodes handled the inventory allocation algorithm and the whole thing ran on a $10 VPS.

Example 3: AI content repurposing. Blog post published to WordPress, n8n webhook fires, LangChain agent extracts key points, generates five Twitter posts and a LinkedIn version, queues to Buffer via API, and sends a Slack notification with preview. Took three hours to build and saves six hours per week.

When to Use Make.com

Make.com deserves more credit than it gets from developers. The visual scenario builder is genuinely excellent, and for non-technical teams, it's the right call more often than not.

Your Team Is Not Technical

Make.com's interface is the best in class for visual workflow building. You can hand it to a marketing manager, ops lead, or founder who knows nothing about code and they will figure it out. n8n is more opinionated and requires more patience.

You Need Quick Setup With Common Apps

Make.com has 1,000+ pre-built app connectors with polished UIs for authentication. Connecting HubSpot, Slack, Airtable, Gmail, and Typeform is genuinely click-and-done. n8n has OAuth support too, but Make.com's connectors tend to expose more of each app's API surface through the visual UI.

Your Complexity Is Moderate

Branching, filtering, aggregating, iterating - Make.com handles all of this well visually. The problems start when you need custom logic that doesn't map to a pre-built module. At that point you're writing HTTP requests anyway and n8n becomes the better choice.

Real Make.com Examples from Client Work

Example 1: Marketing reporting dashboard. A 10-person agency needed weekly reports pulling data from Google Ads, Facebook Ads, and HubSpot into a Google Sheet. A marketing coordinator built the entire Make.com scenario in a day using their pre-built connectors. No developer time needed.

Example 2: Client onboarding sequence. A consulting firm triggered a multi-step onboarding: new client signs in Docusign, Make.com starts a sequence - creates Notion workspace, sends welcome email, adds to HubSpot, creates Slack channel, schedules kickoff in Calendly. Non-technical ops person built and maintains it.

Example 3: Social media monitoring. Brand monitoring across Twitter, Reddit, and Google Alerts, filtering for specific keywords, deduplicating mentions, routing to Slack or Notion based on sentiment. The scenario is complex visually but uses only pre-built modules, Make.com's strength.

When to Go Custom

Custom code is often the wrong answer - but when it's right, it's clearly right.

Your Logic Is Proprietary

If the automation logic itself is part of your competitive advantage, a pricing algorithm, a matching engine, a fraud detection system, you should not build it inside a third-party platform you do not control. Write the code. Own it.

You Need Peak Performance

Automation platforms add latency. A webhook hitting n8n might take 200-500ms to execute. A custom Node.js function on your own infrastructure can respond in under 20ms. For real-time systems, customer-facing interactions, or anything time-sensitive, that gap matters.

The Automation Is Part of Your Product

If you are building a feature that automates something for your users - not just internal process automation - you almost certainly need custom code. Users should not be aware that a third-party tool is running their experience.

You Have Unusual Integration Needs

Sometimes the API you need to call does not have an n8n node or Make.com module. Sometimes it requires OAuth flows, streaming responses, binary file handling, or custom authentication schemes that platforms cannot cleanly support. Custom code removes those constraints entirely.

Real Custom Code Examples from Client Work

Example 1: Real estate matching engine. Built a Node.js service that runs every 15 minutes, pulls new property listings from multiple APIs, scores them against buyer preference profiles using a custom algorithm, and sends personalized alerts. The matching logic was too business-specific for a no-code platform, and the client wanted to own the IP.

Example 2: Payment dunning system. A SaaS company needed custom retry logic for failed payments: retry at 3 days, 7 days, 14 days with different email copy each time, pause retries if the customer contacts support, restart if they update payment info. The branching conditions around customer state were too complex to maintain visually. Custom Node.js worker with a Postgres state machine handled it cleanly.

Example 3: Real-time webhook processor. A fintech client received 50,000 bank webhooks per day, each requiring sub-100ms processing to update customer account balances. Automation platforms were not a consideration. A Fastify server with a Bull job queue handled it.

Code Side by Side: The Same Automation in Each Tool

To make this concrete, here is the same automation implemented three ways: receive a form submission, enrich with company data, score the lead, and save to a CRM.

n8n Workflow (JSON excerpt)

This is what an n8n workflow node looks like in the exported JSON format:

{
  "nodes": [
    {
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {
        "path": "lead-capture",
        "responseMode": "lastNode"
      },
      "position": [240, 300]
    },
    {
      "name": "Enrich Lead",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "method": "GET",
        "url": "https://company.clearbit.com/v2/companies/find",
        "queryParameters": {
          "parameters": [
            { "name": "domain", "value": "={{ $json.email.split('@')[1] }}" }
          ]
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "position": [460, 300]
    },
    {
      "name": "Score Lead",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const lead = $input.first().json;\nconst company = $('Enrich Lead').first().json;\n\nlet score = 0;\nif (company.metrics?.employees > 50) score += 30;\nif (company.metrics?.estimatedAnnualRevenue > 1000000) score += 25;\nif (lead.timeline === 'immediate') score += 25;\nif (lead.budget > 5000) score += 20;\n\nreturn [{ json: { ...lead, company, score, tier: score > 70 ? 'hot' : score > 40 ? 'warm' : 'cold' } }];"
      },
      "position": [680, 300]
    },
    {
      "name": "Save to HubSpot",
      "type": "n8n-nodes-base.hubspot",
      "parameters": {
        "resource": "contact",
        "operation": "upsert",
        "email": "={{ $json.email }}",
        "additionalFields": {
          "leadScore": "={{ $json.score }}",
          "lifecyclestage": "={{ $json.tier === 'hot' ? 'opportunity' : 'lead' }}"
        }
      },
      "position": [900, 300]
    }
  ]
}

n8n gives you expression syntax (={{ }}), native HubSpot nodes, and a Code node where you write real JavaScript. The workflow is version-controlled as JSON.

Make.com Scenario (Module config)

Make.com does not export as readable JSON in the same way, but here is what the module configuration looks like conceptually:

{
  "scenario": {
    "name": "Lead Capture and Score",
    "modules": [
      {
        "id": 1,
        "type": "webhook",
        "name": "Receive Form Submission",
        "config": { "method": "POST" }
      },
      {
        "id": 2,
        "type": "http.makeRequest",
        "name": "Clearbit Enrichment",
        "config": {
          "url": "https://company.clearbit.com/v2/companies/find",
          "method": "GET",
          "qs": [{ "key": "domain", "value": "{{split(1.email, '@')[1]}}" }],
          "headers": [{ "key": "Authorization", "value": "Bearer {{connection.apiKey}}" }]
        }
      },
      {
        "id": 3,
        "type": "builtin.basicRouter",
        "name": "Route by Company Size",
        "routes": [
          {
            "label": "Large Company",
            "filter": { "condition": "{{2.metrics.employees}}", "operator": "greater", "value": "50" }
          },
          {
            "label": "Small Company",
            "filter": { "condition": "{{2.metrics.employees}}", "operator": "less", "value": "50" }
          }
        ]
      },
      {
        "id": 4,
        "type": "hubspot.createUpdateContact",
        "name": "Save to HubSpot",
        "config": {
          "email": "{{1.email}}",
          "properties": [
            { "name": "lead_score", "value": "75" }
          ]
        }
      }
    ]
  }
}

Notice what is missing: the actual scoring logic. Make.com would require a separate formula field or a router with multiple branches to approximate what the n8n Code node does in ten lines. For simple scoring this works, but the logic becomes unwieldy as conditions grow.

Custom Node.js Implementation

import Fastify from "fastify";
import { clearbit } from "./lib/clearbit";
import { hubspot } from "./lib/hubspot";
import { slack } from "./lib/slack";
 
const app = Fastify();
 
interface LeadPayload {
  email: string;
  name: string;
  company: string;
  timeline: "immediate" | "quarter" | "year";
  budget: number;
  message: string;
}
 
function scoreLead(lead: LeadPayload, company: ClearbitCompany): number {
  let score = 0;
 
  // Company signals
  if ((company.metrics?.employees ?? 0) > 50) score += 30;
  if ((company.metrics?.estimatedAnnualRevenue ?? 0) > 1_000_000) score += 25;
  if (company.category?.sector === "Technology") score += 10;
 
  // Lead signals
  if (lead.timeline === "immediate") score += 25;
  if (lead.budget > 10_000) score += 20;
  else if (lead.budget > 5_000) score += 10;
 
  return Math.min(score, 100);
}
 
app.post<{ Body: LeadPayload }>("/webhooks/lead", async (request, reply) => {
  const lead = request.body;
 
  // Enrich with company data
  const domain = lead.email.split("@")[1];
  const company = await clearbit.company.find({ domain });
 
  // Score the lead
  const score = scoreLead(lead, company);
  const tier = score >= 70 ? "hot" : score >= 40 ? "warm" : "cold";
 
  // Save to CRM
  await hubspot.contacts.upsert({
    email: lead.email,
    properties: {
      firstname: lead.name.split(" ")[0],
      lastname: lead.name.split(" ").slice(1).join(" "),
      lead_score: score,
      lead_tier: tier,
      lifecyclestage: tier === "hot" ? "opportunity" : "lead",
    },
  });
 
  // Alert for hot leads
  if (tier === "hot") {
    await slack.postMessage({
      channel: "#hot-leads",
      text: `Hot lead: ${lead.name} at ${lead.company} (score: ${score})`,
    });
  }
 
  return reply.code(200).send({ received: true, score, tier });
});
 
app.listen({ port: 3000 });

This is cleaner to read, easier to test, and trivially extensible. The trade-off is that you wrote it, you host it, and you maintain it. There is no drag-and-drop.

Real Project Examples

Project 1: Agency Client Reporting (Make.com)

Client: 15-person digital marketing agency Problem: Manually pulling weekly reports from 6 ad platforms into Google Sheets took 5 hours every Monday Tool chosen: Make.com Why: Marketing team owns the automation, not the developer. Pre-built connectors for Google Ads, Meta Ads, LinkedIn Ads, and Google Sheets. No code needed. Result: 5 hours saved weekly. Marketing manager built and maintains it independently. Cost: $18.82/month on Make.com Pro

Project 2: SaaS Lead Qualification (n8n)

Client: B2B SaaS startup, 300+ inbound leads/week Problem: Sales team spending 4 hours/day manually scoring leads, hot leads going cold Tool chosen: n8n self-hosted Why: Needed custom scoring algorithm, OpenAI integration for message analysis, complex routing logic. Developer on team to maintain it. Result: 0 manual qualification hours. Response time under 2 minutes. 3x increase in hot lead conversion. Cost: $12/month (server + OpenAI)

Project 3: Real-Time Inventory Sync (Custom Node.js)

Client: Multi-location retail brand Problem: Inventory levels across 12 locations and 3 warehouses out of sync. Overselling happening daily. Tool chosen: Custom Node.js service Why: Required sub-200ms response time on order placement, complex allocation logic based on shipping zones, direct integration with proprietary warehouse management system Result: Zero oversells since launch. Order allocation accuracy 99.8%. Cost: $25/month (dedicated VM)

Decision Framework

When I get a new automation request, I work through these questions in order:

Automation Tool Decision Flowchart

Work through each question in order

1. Is this automation core to your product or user experience?

Yes → Custom CodeNo → continue

2. Does it require sub-100ms response time or 1M+ monthly executions?

Yes → Custom CodeNo → continue

3. Does it involve proprietary logic or data that must stay on your infrastructure?

Yes → n8n self-hostedNo → continue

4. Will a non-developer need to build or maintain this?

Yes → Make.comNo → continue

5. Does it need custom code, AI agents, or complex conditional logic?

Yes → n8nNo → Make.com

Volume tiebreaker

If cost is a concern and monthly executions exceed 10K, self-hosted n8n beats Make.com every time regardless of other factors.

The Short Version

  • Non-technical person needs to own it: Make.com
  • Complex logic, AI integration, high volume, or data privacy: n8n
  • Core product feature, unique algorithm, or sub-100ms performance needed: Custom code

Common Mistakes I See

Mistake 1: Using Custom Code for Commodity Automations

A developer sees a simple webhook-to-CRM flow and immediately spins up a Node.js service. That service now needs hosting, monitoring, deployment pipelines, and maintenance. n8n would have handled it in 20 minutes. Save custom code for when it actually matters.

Mistake 2: Using Make.com for High-Volume Workflows

A startup picks Make.com because it looks friendly. Six months later they have 500K monthly operations and a $300/month bill for what would cost $20 on self-hosted n8n. The migration is painful because their scenarios are complex. Plan for volume early.

Mistake 3: Building Complex Logic in Make.com Routers

Make.com's router with 8 branches and 40 filter conditions is a maintenance nightmare. If you find yourself building deeply nested routing logic in Make.com, you have outgrown it. Move to n8n where Code nodes keep that logic readable.

Mistake 4: Treating n8n as a Drop-In Zapier Replacement

n8n requires more setup and thought than Zapier or Make.com. If you set it up and immediately try to use it like Zapier - expecting everything to just work with no configuration - you will be frustrated. Invest a few hours understanding nodes, expressions, and credentials. It pays off.

Mistake 5: Not Planning for Failures

All three tools can and do fail. Webhooks get missed. API rate limits get hit. Third-party services go down. Make.com has decent built-in error handling. n8n has retry logic and error workflows. Custom code has whatever you build. Whatever tool you choose, design for failure from day one.

My Honest Take After 50+ Projects

Make.com is often underestimated by developers. For a non-technical team that needs to own their automations, it is the right call - even if the per-operation pricing model stings at scale. I have handed Make.com scenarios to marketing managers and operations coordinators who maintained them independently for months without calling me.

n8n is my daily driver for client work. The combination of visual building, Code nodes, self-hosting, and native AI support covers 80% of what I need. The learning curve is real but manageable. The economics at scale are hard to argue with.

Custom code I reserve for situations where the other tools genuinely cannot deliver. This happens less than you might expect. When it does happen, it is usually a performance requirement, a proprietary algorithm, or a product-level feature - and in those cases, there is no debate.

The worst outcome is mismatching tool to problem. Complex logic in Make.com becomes unmaintainable. Commodity workflows in custom code become expensive to maintain. Non-technical ownership of n8n becomes a support burden.

Pick the tool that matches your team, your volume, and the nature of the logic. That is the whole framework.


Working on an automation and not sure which direction to go? I offer free 30-minute calls to walk through your specific use case and recommend the right approach. Get in touch and we will figure it out together.

Share:

Get practical engineering insights

AI voice agents, automation workflows, and shipping fast. No spam, unsubscribe anytime.