The Three Tools Side by Side
Zapier is the market leader and the most approachable entry point. It is a pure SaaS platform — you do not install anything, you do not manage a server, and you are priced per task (an individual action execution). The connector library is enormous: Zapier supports thousands of apps with pre-built triggers and actions. The tradeoff is cost at volume. At moderate workflow execution rates — thousands of tasks per month — Zapier’s pricing climbs quickly. The platform is optimized for business users building automations on top of existing SaaS apps, not for developers running high-throughput custom pipelines.
Make (formerly Integromat) occupies the middle ground. It is also a SaaS platform, but its pricing unit is operations (individual node executions within a scenario) rather than tasks, which makes it cheaper for multi-step workflows. Make’s visual editor is more powerful than Zapier’s — it supports iterators, aggregators, routers, and complex data transformation natively. It is a good choice for teams that need serious automation capability without the overhead of self-hosting.
n8n is an open-source workflow automation tool with a visual editor that is structurally similar to Make. The key distinction: it can be self-hosted. n8n Cloud exists as a managed option, but the self-hosted deployment model is what makes n8n a different category of tool for operators who are comfortable running their own infrastructure. Self-hosted n8n means you control the execution environment, the data never leaves your infrastructure, and the marginal cost per workflow execution is effectively zero beyond the base compute cost of the host.
When Make and Zapier Are the Right Call
Self-hosting is not always the right answer, and the upgrade prompt for the Lead Enrichment app’s workflow stack was deliberate about recognizing that. Make and Zapier are the right call when:
- The team is not technical. Zapier requires no infrastructure knowledge to operate. If the person maintaining the workflows is a marketer or operations manager — not a developer — Zapier’s reliability-as-a-managed-service is a meaningful benefit.
- Execution volume is low and stable. For a business running 500–2,000 tasks per month, Zapier’s starter tier is cost-effective and operationally simple. The crossover point where self-hosting becomes cheaper varies by workflow complexity and execution frequency, but for most small-to-medium automation use cases it is higher than people expect.
- The connectors you need are in the Zapier library. Zapier’s pre-built integrations with SaaS tools are often better than n8n’s equivalents — more actions exposed, more reliable authentication flows. If your automation stack is purely composed of popular SaaS apps and you do not need custom HTTP nodes or database integrations, Zapier is a reasonable choice.
- You do not want to own uptime. Self-hosted n8n requires you to monitor your host, manage updates, handle database backups, and respond when something breaks. Zapier handles this transparently. That operational overhead is real, and for an operator whose core work is not infrastructure management, the SaaS tax is often worth paying.
Why I Picked Self-Hosted n8n
The Lead Enrichment app is a production system running against 2,656 California contractor prospects. Its workflow layer handles: CRM webhook dispatch, inbound voice classification, voicemail transcription routing, multi-vendor enrichment sequencing, email warmup cadence, SEO data sync, and operator alerting. At that scale and that integration depth, Make and Zapier were not viable options for three specific reasons.
First, the execution volume. The enrichment waterfall alone — BetterContact, Serper, ZeroBounce, Twilio Lookup v2, Wappalyzer, Google Places, CSLB — processes multiple API calls per prospect. Running those calls through a cloud automation platform at task- or operation-based pricing would be expensive. Self-hosted n8n runs on a $6/month ARM64 VPS; the per-execution cost is zero.
Second, the integration depth. The Lead Enrichment app’s n8n workflows make direct HTTP calls to the FastAPI application, read from and write to the PostgreSQL database via Postgres nodes, and communicate with Matrix-protocol operator alerts. These are not pre-built connector integrations — they require custom HTTP nodes, environment variable injection, and structured payload handling. n8n handles this cleanly; Zapier would require custom app definitions or workarounds for every internal API call.
Third, the tick architecture (more on this below) requires precise scheduling at short intervals — some workflows run every two minutes. Cloud automation platforms often cap polling intervals at 5 or 15 minutes on lower pricing tiers. Self-hosted n8n has no scheduling floor.
The systemd-to-Docker Migration
The original deployment ran n8n as a systemd service directly on the host. This worked, but created two problems: update management required manual intervention at the host level, and the n8n process shared the host environment with other services in a way that created implicit dependencies (specific Node.js version, shared directory paths, no isolation from host package upgrades).
The migration to ARM64 Docker on April 27, 2026 resolved both. The Docker deployment model treats n8n as a containerized unit with a declared dependency on a Postgres container (external, pre-existing), an environment file for secrets, and a named volume for the n8n data directory. The compose file is a complete specification of the deployment — version pinned, volume mapped, network isolated.
The migration steps in practice:
- Export all workflow definitions from the running n8n instance as JSON (n8n UI → Workflows → Export). This is the safety copy. Keep it.
- Stop the systemd service and verify the n8n SQLite database location (or Postgres connection string if already using Postgres).
- Write the Docker Compose file with the official n8n image pinned to a specific version, the N8N_ENCRYPTION_KEY environment variable, and the volume mount for the data directory.
- Start the container and verify n8n boots against the existing database (if migrating from SQLite: copy the database file into the mounted volume before starting).
- Verify all workflows are present and all credentials decrypt correctly before decommissioning the systemd service.
The critical non-obvious step: the N8N_ENCRYPTION_KEY must be identical in the Docker deployment to what was used in the systemd deployment. n8n encrypts credential values at rest using this key. A different key means every credential fails to decrypt and must be re-entered manually.
The 11 Workflows in Production
At the time of writing, the Lead Enrichment app’s n8n instance runs 11 active workflows. They fall into four functional groups:
CRM and inbound routing (3 workflows). Webhook receiver for GoHighLevel CRM contact events; inbound voice call classification (Twilio → n8n → FastAPI → Matrix alert); voicemail transcription dispatch (Twilio recording URL → Whisper → classification → Matrix alert with full transcript).
Enrichment and outreach dispatch (4 workflows). Tick-based enrichment queue reader (fires every 2 minutes, reads pending prospects from the queue, dispatches to FastAPI enrichment endpoint); enrichment status monitor (checks for stalled enrichment jobs and requeues); email warmup tick (fires every 3 minutes, checks the warmup schedule table, dispatches sends at rate-controlled intervals); voicemail campaign tick (fires on a longer interval, reads voicemail campaign queue, dispatches Twilio AMD calls).
SEO intelligence sync (2 workflows). GSC data pull (Google Search Console API → Postgres, nightly); GA4 session and event sync (GA4 Data API → Postgres, nightly). Both write to tables read by the SEO intelligence module in FastAPI.
Operational monitoring (2 workflows). Daily summary dispatch (aggregates enrichment counts, email activity, and voicemail delivery stats and posts to Matrix operator console); error alert workflow (fires on any n8n execution failure and posts the error payload to Matrix).
The Tick Architecture
The tick architecture is the most important design decision in the Lead Enrichment app’s workflow layer, and the one most worth explaining for anyone building a similar system.
The naive approach to workflow-driven outreach is event-driven dispatch: when a new prospect is added to the CRM, immediately trigger enrichment; when enrichment completes, immediately trigger the outreach sequence. This seems clean but creates two problems in practice. First, burst load: if 50 prospects are imported at once, 50 simultaneous enrichment chains fire. Most enrichment APIs have rate limits. Second, retry complexity: if an enrichment API is temporarily unavailable, you need a retry mechanism layered on top of the event-driven dispatch.
The tick pattern solves both. The architecture is:
- Inbound events (new prospect added, voice call received, voicemail recorded) write to a queue table in Postgres. The queue record includes: the prospect ID, the action type, the priority, and the created_at timestamp.
- A scheduled n8n workflow fires every N minutes (the “tick”). On each execution, it reads up to M records from the queue (M is the rate limit: e.g. 5 enrichment requests per tick = 150 per hour). It dispatches those records to the appropriate FastAPI endpoint and marks them as in_progress.
- FastAPI handles the actual enrichment — API calls, database writes, result classification. On completion, it marks the queue record as completed or failed. Failed records are retried on the next tick up to a maximum attempt count, then moved to a dead letter queue for review.
The result is a system where the rate of outbound API calls is controlled by the tick interval and the per-tick dispatch limit — not by the rate of inbound events. The queue is inspectable at any point: you can query it to see what is waiting, what is in flight, and what has failed. And adding a new prospect to the system during a burst import simply adds a record to the queue; the tick will reach it on the next cycle.
Operational Tradeoffs: Backup, Secrets, Monitoring
Self-hosting n8n means owning three operational concerns that managed platforms handle for you.
Backup. n8n stores workflow definitions, execution history, and encrypted credentials in its database. The backup strategy has two parts: database backup and encryption key backup. For Postgres, a nightly pg_dump to an offsite location is the minimum viable approach. For the encryption key (N8N_ENCRYPTION_KEY), store it in a secrets manager or encrypted vault — without it, a database backup is not restorable because credentials cannot be decrypted. Workflow definitions can also be exported as JSON from the n8n UI; this is useful as a version-control supplement.
Secrets management. n8n integrates with external credential stores, but the simplest production pattern is environment variable injection at container startup. The Docker Compose env_file directive points to a secrets file that is not committed to version control. Sensitive values — API keys for every enrichment vendor, Twilio auth tokens, database credentials — live there. The risk is secret sprawl: a long env file maintained manually across multiple services. The mitigation is a secrets audit on every vendor credential renewal cycle.
Monitoring. Without managed-platform uptime monitoring, you need to detect when n8n itself is down. The approach in the Lead Enrichment app is a watchdog workflow: a minimal n8n workflow on a 5-minute schedule that does nothing except succeed. A separate monitoring tool (UptimeRobot on the free tier) pings the n8n health endpoint at the same interval. If the health endpoint stops responding, the alert fires. The n8n error alert workflow (one of the 11) catches execution failures and posts them to the Matrix operator console — this handles in-process errors but not host-level failures, which is why the external health check matters.
When Self-Hosted Is the Wrong Call
Self-hosted n8n is the right choice for the Lead Enrichment app for the reasons described above — high execution volume, deep integration with internal infrastructure, short scheduling intervals, and an operator who is comfortable managing Docker containers and Postgres. It is the wrong choice in a different context.
If you are a solo operator or a small team building automations on top of SaaS apps — HubSpot, Airtable, Slack, Google Workspace — and your workflows run a few hundred times a day, the monthly cost of Zapier or Make is probably less than the time cost of maintaining self-hosted infrastructure. The $6/month VPS is cheap; the time spent on backups, updates, and debugging container issues is not.
If the people who will maintain the workflows after you are not developers, self-hosting is a liability. Zapier’s managed reliability and its approachable UI are worth the cost when the alternative is a workflow layer that only one person understands how to operate.
And if you need enterprise-grade reliability with SLA guarantees and support contracts, n8n Cloud (not self-hosted) or Make Business is the right answer. Self-hosted n8n gives you control, not reliability guarantees. Those are different things.
The decision framework: self-host when execution volume is high, when integration depth requires custom HTTP nodes or database access, when scheduling precision matters, and when the operator is comfortable owning the infrastructure. Use a managed platform when any of those conditions is not met.