FlowKit

Migrating from n8n Cloud to a self-hosted instance: the step-by-step guide

Published 27 July 2026 · 7 min read

Start on n8n Cloud, then migrate to self-hosted once volume or compliance requirements justify it: that's the most common trajectory, the one we already described in our self-hosted vs Cloud comparison. The good news is that n8n workflows are portable by design — a JSON exported from Cloud imports as-is onto your server. The less good news is that everything else doesn't follow automatically: credentials, OAuth connections, webhook URLs. This guide walks through the migration step by step, in the right order, so you can switch without breaking your automations in production.

Why migrate — and why sometimes stay

Three reasons come up consistently among those leaving Cloud:

  • Cost at high volume. n8n Cloud bills by monthly execution tiers (see our n8n Cloud pricing guide). While volume stays modest, the subscription is easy to justify; once AI workflows run hundreds of times a day, self-hosting brings the marginal cost of an execution close to zero — our analysis of the real cost of self-hosted n8n puts numbers on the tipping point.
  • Control over your data. On your own server, your workflow payloads (customer emails, CRM data, documents) no longer pass through a third-party processor. For businesses under strict GDPR requirements, that's often the deciding argument.
  • Technical freedom. Advanced environment variables, community nodes without restrictions, fine-grained control over binary data storage or queue mode: self-hosting unlocks everything Cloud locks down by design.

And one good reason to stay on Cloud: maintenance. Updates, backups, availability, security — all of it becomes your responsibility when self-hosting. If nobody on the team wants to run a server, the Cloud subscription buys peace of mind that's worth its price. The migration described here is for those who've done that math and chosen control.

Step 1 — Prepare the target instance before touching Cloud

The golden rule: the target must be fully operational before you export anything. A migration where you scramble to set up the server while workflows are already switched off on the Cloud side is the surest way to lose a day. This isn't just intuition: the systematic review by Jamshidi, Ahmad, and Pahl on cloud migrations (Cloud Migration Research: A Systematic Review, IEEE Transactions on Cloud Computing, 2013 — see it on Google Scholar) shows that most migration risk concentrates in the planning and transition phases, when both environments coexist. In other words: prepare, then switch over gradually — never the other way around.

Concretely, before the cutover:

  1. Stand up the instance with Docker Compose following our n8n Docker installation guide: PostgreSQL rather than SQLite, persistent volumes, N8N_ENCRYPTION_KEY set explicitly and stored somewhere safe.
  2. Configure HTTPS and your domain name from day one, with Traefik or Caddy. OAuth connections and webhooks require a public HTTPS URL — without it, recreating Google or Slack credentials is impossible.
  3. Verify the instance is alive: create a test workflow with a webhook, call it from outside, and confirm the execution shows up in the history.

Until all three boxes are green, don't touch anything on the Cloud side.

Step 2 — Export your workflows from n8n Cloud

Two methods, depending on volume:

Manual export from the UI. Open each workflow, ⋯ menu → Download: you get a complete JSON file (nodes, connections, settings). Perfect for up to a dozen workflows.

Bulk export via the REST API. n8n exposes a public API: create an API key in your Cloud account settings, then query the workflows endpoint:

curl -H "X-N8N-API-KEY: your-key" \
  "https://your-account.app.n8n.cloud/api/v1/workflows"

A small script is enough to loop over the results and write one JSON file per workflow. Check pagination in the API documentation so nothing gets missed — exact details (parameters, limits) can vary between versions.

Two habits worth adopting here: export all workflows, including inactive ones and drafts (you always end up regretting the one you left behind), and commit those JSON files to a Git repository immediately — this is the perfect moment to adopt the discipline described in our guide to backing up and versioning workflows with Git.

Step 3 — The critical point: credentials don't migrate

This is the trap of the migration, so let's be blunt: your credentials won't come along. n8n encrypts every credential with the encryption key of the instance that created it. Between two self-hosted instances, you can migrate the database and the N8N_ENCRYPTION_KEY together to keep credentials intact. But coming from n8n Cloud, you don't have access to that key: manual recreation on the target is the only path.

In practice:

  1. List every credential in use (the Cloud Credentials screen shows them at a glance).
  2. Gather the original secrets: API keys from provider consoles (OpenAI, Stripe, Brevo…), SMTP credentials, tokens. If a key can't be found, regenerate it at the provider — it's also a good opportunity to rotate old secrets.
  3. Recreate each credential on the target instance, with exactly the same name as on Cloud: when importing the JSON, n8n matches nodes to credentials by name, and identical naming spares you from reopening every node one by one.

Step 4 — Redo the OAuth connections

OAuth credentials (Google, Slack, Microsoft, HubSpot…) require one extra step: the callback URL changes. It used to contain the app.n8n.cloud domain; it now points to your own. For each OAuth connection:

  1. Open the provider's console (Google Cloud Console, Slack app settings…) and add the new redirect URL that n8n displays on the credential creation screen.
  2. Create the credential on the target and run the authorization flow (Connect my account).
  3. Test with a simple node (list Drive files, post to a test channel) before considering the connection valid.

If you were using Cloud's pre-configured OAuth credentials (where n8n provides its own OAuth client), you'll need to create your own OAuth application at each provider — budget a few extra minutes per service.

Step 5 — Import the workflows and update webhook URLs

The import is the easy part: Import from file in the UI, or the POST /api/v1/workflows endpoint of your instance's API. Import everything but leave the workflows inactive for now.

Then comes the second trap of the migration: every webhook URL changes, since the domain changes. Every third-party service that used to call https://your-account.app.n8n.cloud/webhook/... must now call https://your-domain.com/webhook/.... Go through:

  • Stripe, Shopify, WooCommerce, GitHub webhooks… registered in those services' dashboards;
  • forms (Tally, Typeform, website forms) posting to an n8n webhook;
  • in-house integrations and external cron jobs calling your endpoints;
  • webhook URLs hard-coded… in other n8n workflows.

A three-column table — service, old URL, new URL — keeps anything from slipping through. It's exactly the kind of inventory you'll wish you had kept from the start.

Step 6 — Parallel run and gradual cutover

Don't cut Cloud off in one go. The transition phase — both environments coexisting — is the one the migration literature identifies as the riskiest; it's also the one you can best de-risk:

  1. Rank your workflows from least to most critical.
  2. Switch them over one by one: activate on the target, update the webhook at the third-party service (for webhook-triggered workflows, flipping the URL is naturally atomic: only one environment receives the calls), then deactivate on the Cloud side. For scheduled workflows, deactivate on Cloud before activating on the target, or you'll get duplicate emails and duplicate writes.
  3. Watch each workflow for a few days under real conditions before moving to the next.
  4. Keep the Cloud subscription active for one to two weeks after the last cutover, as a safety net, before cancelling.

Final checklist before calling the migration done

  • All workflows imported, tested, and active on the target; none still active on Cloud
  • All credentials recreated, OAuth connections revalidated service by service
  • All webhook URLs updated at third parties (and verified with a real call)
  • N8N_ENCRYPTION_KEY backed up off the server
  • Automated PostgreSQL backups with a tested restore — a backup that's never been restored isn't a backup
  • Monitoring in place: container, disk, failed executions
  • An update procedure defined (read the changelog, back up, update)
  • The Cloud export archived in Git as a snapshot of day-zero state

And what about your workflows?

That's the hidden virtue of this portability: anything expressed as n8n JSON works on both sides, and will keep working. FlowKit packs are built on exactly that principle — the AI Inbox Pack ($79), the RAG Assistant Pack ($119), and the Compliance & Audit Pack ($149) import as JSON onto any instance, Cloud or self-hosted. Whether you migrate today or in a year, your workflows — bought or built — follow you. That's exactly what you want from an automation tool: a hosting choice that stays reversible.

FAQ

Frequently asked questions

Can you export all your n8n Cloud workflows at once?

Yes, two ways: from the UI, each workflow exports as JSON (⋯ menu → Download), and for bulk exports the n8n REST API exposes workflows via /api/v1/workflows with an API key created in your account settings. A small script can then fetch every workflow as JSON in a single pass.

Can n8n Cloud credentials be exported to a self-hosted instance?

No, not in usable form. Credentials are encrypted with a key specific to the original instance, and on n8n Cloud you don't have access to that key. You therefore have to recreate them manually on the target instance: re-enter API keys and redo OAuth connections. This is the main chunk of work in the migration.

Why do OAuth connections (Google, Slack, etc.) need to be redone after migrating?

Because the OAuth callback URL contains the instance's domain. Moving from your-account.app.n8n.cloud to your own domain changes the redirect URL: you have to register it in the provider's console (Google Cloud Console, Slack app settings, etc.) and re-run the authorization flow from the new instance.

How long does a migration from n8n Cloud to self-hosted take?

For a dozen workflows: roughly half a day to stand up the target instance (Docker + HTTPS), then a few hours for the import, credential recreation, and webhook updates. Then plan one to two weeks of running both environments in parallel before cancelling the Cloud subscription, to validate each workflow under real conditions.

Bundle FlowKit Complet

€269