Self-Host Nango Only When the Connection Meter Bites
Self-host Nango only when the connection meter starts to bite. Where the hosted line stops paying, what self-hosting really costs you, and the switch signal.
Filed under Decision Guides· see every report on this topic
Verdict. If you are the technical founder of a micro-SaaS selling three to five integrations, use hosted Nango or do nothing while you validate demand. Self-host when measured connections × the vendor’s actual per-connection price exceeds your recorded operating cost and the stack has run unattended for 30 days. Compare Merge only after checking its current price and the exact providers you need.
This is a receipts-first report from a live Nango deployment checked on 21 August 2026. It does not claim a price, SLA, throughput, or universal catalog without a receipt. For the same discipline on infrastructure that appears cheap until it gets hot, read the local LLM field guide.
The operator and the leak
Priya is a technical founder with a small B2B product, not a “connect everything” plan. Her customers ask for GitHub, an everyday SaaS tool, and one niche system. Each connection can require an OAuth application, callback, encrypted credentials, refresh handling, API-version work, and support when consent fails.
The choice is between a vendor’s recurring connection meter, rebuilding provider plumbing, or operating connector infrastructure yourself. Our deployment shows the smallest credible self-hosted shape: Nango server, PostgreSQL, and Redis on an existing AI workstation. It does not show that self-hosting is cheap. That host also runs LLM, GBrain, and other workloads, and the Nango runbook records existing port owners at 5432, 3000, 8000, and 3131.
Compare the operating model, not the logo
“Do nothing first” belongs in the comparison: one untested customer request is not integration strategy.
| Approach | Best fit | Cost shape | Main catch |
|---|---|---|---|
| Hosted Nango | Early connector validation | Monthly bill; verify current pricing | Vendor runs the ops layer |
| Self-hosted Nango | Proven repeat demand | Host resources + operator time | You own auth, upgrades, ports |
| Merge | Verified catalog fit | Verify at merge.dev/pricing, fetched 2026-08-21 | Do not assume coverage or price |
| Raw OAuth | One narrow, stable provider | Engineering + maintenance time | You own credential lifecycle |
| Do nothing first | Unproven demand | $0 until evidence arrives | Buyer may need a manual path |
Hosted Nango is the default when Priya has only a few integrations and no measured monthly crossover. No current Nango pricing receipt was captured for this article, so it is not quoted here.
Self-hosted Nango has a real operating baseline but no financial conclusion. Merge is a vendor option, not a made-up dollar comparison: verify its pricing at merge.dev/pricing, fetched 2026-08-21. Raw OAuth can fit one stable core provider, but then you own app registration, client-secret rotation, callbacks, authorization state, refresh failures, provider quirks, and the audit trail. Before any of these, record customer, provider, requested action, revenue at risk, setup time, and whether a manual export, CSV, or assisted setup solved the need. See the Workflow Decision Lab primer for separating a tool request from the workflow leak.
Run the smallest stack with the right auth boundary
On 21 August, docker ps --filter name=nango showed the following live stack. The Nango server had been up about 15 hours; Redis about 30 hours. The server was bound to the workstation LAN on ports 3003 and 3009. This proves a running deployment at inspection time, not month-long reliability.
| Service | Image | Persistent state | Live memory, 21 Aug 2026 |
|---|---|---|---|
| Nango server | nangohq/nango-server:hosted |
Depends on DB and Redis | 364.5 MiB |
| PostgreSQL | postgres:16.0-alpine |
Local bind mount | 32.99 MiB |
| Redis | redis:7.2.4 |
Local bind mount | 3.609 MiB |
The compose file at /home/kit/projects/nango/docker-compose.yaml names these three services and a dedicated Docker network. PostgreSQL and Redis use persistent local bind mounts. The server image is hosted, not a version pin; its compose comment says to pin a released tag before public exposure. Treat that as change control.
The active remote compose has FLAG_AUTH_ENABLED: "false". Dashboard and private management calls use HTTP Basic auth, and private environment-scoped routes also need ?env=dev; omit it and the runbook records invalid_env. Public /integrations, /connections, and proxy calls use a separate Bearer Environment API key. The local mirror at /Users/kit/projects/infra-setup/nango/docker-compose.yaml still says FLAG_AUTH_ENABLED: "true"; it is a warning, not evidence of the active mode.
The authentication paths serve different jobs:
| Path | Credential | Required detail |
|---|---|---|
| Dashboard and private management API | HTTP Basic auth | Add ?env=dev to environment-scoped routes |
| Public integration, connection, and proxy API | Bearer Environment API key | Keep separate from dashboard credentials |
| Bootstrap helper | Dedicated hermes-agent key |
environment:* scope; file mode 0600 |
/home/kit/projects/nango/bootstrap-nango.sh creates the hermes-agent environment key through the private, Basic-auth, ?env=dev route. It writes ~/.nango/apikey.hermes mode 0600 and verifies a Bearer GET /integrations without printing the secret. /home/kit/projects/nango/nango_api.py reads that file for public integration, connection, credential, and proxy calls.
One runbook trap is worth keeping: an unknown API path can return dashboard HTML with HTTP 200. Treat a response as successful only if it is authenticated and has the expected JSON shape.
Validate the providers you must sell
The GBrain record sessions/digest/2026-08-20 found 973 providers on 20 August 2026. It verified common communication and analytics SaaS integrations and GitHub PAT; several requested crypto and broker categories were absent. GitHub PAT is a useful zero-registration smoke path because it uses API-key credentials instead of an OAuth app. It does not prove the customer’s difficult provider will work.
List required providers first, then test their connection modes. A large catalog does not close your specific gap.
Price operator work instead of container screenshots
The 21 August docker stats --no-stream receipt found 364.5 MiB for the server, 32.99 MiB for PostgreSQL, and 3.609 MiB for Redis on a host reporting a 60.76 GiB memory limit. This is one sample, not a steady monthly average, peak-load test, backup plan, or recovery test. It excludes host acquisition, backups, monitoring, alerts, upgrade time, outages, and capacity contention with the rest of the workstation.
Do not turn MiB into dollars without a host-cost receipt. Do not allocate the whole 60.76 GiB to Nango. Use dated inputs instead:
Monthly self-host cost = incremental host cost
+ backup and monitoring cost
+ (operator hours × loaded hourly cost)
+ incident and upgrade time
Monthly hosted cost = current vendor base fee
+ (active connections × current per-connection fee)
connection crossover = monthly self-host cost
÷ verified vendor per-connection price
If a vendor charges a base fee, subtract it from the self-host side only after confirming comparable environments, provider catalog, retention, support, compliance requirements, and connection minimums. Until then, no crossover exists. The surprise cost is usually operator time during the first failed OAuth flow or emergency upgrade, not RAM.
Put named failures in the runbook
- Auth-mode mismatch: Basic dashboard credentials are not email-login credentials. Keep the active compose and management flow together; do not use an old local mirror.
- Missing environment scope: private routes need
?env=devin this deployment. - False 200: verify authenticated JSON, not HTTP status alone.
- Port and project collision: the runbook records multiple compose files under one project name and a possible 5432 collision if the wrong file starts. Select the compose file explicitly and inspect state rather than deleting containers at random.
- Catalog hole: 973 providers still omitted several requested crypto and broker categories. Test the exact connection mode before closing a deal.
- “Up” but unusable: a running container does not prove callback, refresh, proxy, or customer consent. Test integration, connection, and a real provider proxy response.
When to stop before adding infrastructure
Do not self-host when you cannot name the three to five repeatedly requested integrations, the provider is in a catalog gap, no one owns updates/backups/rotation/incidents, external availability or security/compliance is undesigned, or you have not measured the hosted bill you would avoid. A LAN-bound home-lab service is not automatically customer-facing production.
The $0 move is a request ledger: customer, provider, requested action, revenue at risk, setup time, and whether a manual route solved it. Repeated requests give you decision inputs.
Bottom line
For a founder with three to five integrations, hosted Nango or delayed integration work is likely cheaper because it avoids visible operator work. This deployment shows a readable three-container stack, separate management and application credentials, a point-in-time memory footprint, and a catalog that is useful but not universal.
Self-host only after your ledger shows a connection-meter crossover and a single connector path covers auth, refresh, host contention, and provider gaps. Without a vendor-price receipt and operator-hours record, the crossover is a hunch.
More on this decision, three ways to look at it:
Sources
- Observed 21 August 2026:
ssh kit@pc 'docker ps --filter name=nango'anddocker stats --no-streamfor the three Nango containers. - Active deployment:
/home/kit/projects/nango/docker-compose.yaml(read 21 August 2026; environment values redacted). - Auth and helper receipts:
/home/kit/projects/nango/bootstrap-nango.shand/home/kit/projects/nango/nango_api.py(read 21 August 2026; no secret values reproduced). - Local inspection mirrors:
/Users/kit/projects/infra-setup/nango/docker-compose.yaml,bootstrap-nango.sh, andnango_api.py(read 21 August 2026). - Catalog record: GBrain
sessions/digest/2026-08-20, catalog research dated 20 August 2026. - Operational gotchas:
nango-selfhosted-opsHermes skill, read 21 August 2026; cross-checked against the active compose and helper scripts. - Merge price: to be verified from merge.dev/pricing, fetched 2026-08-21.
Get the next verdict before it's everywhere.
One email when a new lab post or cost table ships. No spam, no confirmation step — unsubscribe anytime.