is*hosting Blog & News - Next Generation Hosting Provider

How to Migrate n8n Processes to a New Server

Written by Alex I. | Mar 26, 2026 9:00:00 AM

Honestly, you can open pretty much any official data migration guide.

At a high level, we did the same thing — we just pulled the best recommendations from a few different guides, then added what we’ve learned from doing an n8n server migration in real life.

We’ll also suggest skipping a couple of steps to make it easier to migrate n8n, but more on that in the migration section.

If you’re moving from n8n Cloud to self-hosted, you’ll need to export your n8n workflows and handle the transfer manually, then reconfigure everything afterward.

You might be able to ask n8n support for a data dump if you have a lot of data, but we wouldn’t count on an easy n8n cloud migration, as n8n doesn’t have a one-click “n8n migrate” button.

Migrating between servers is a bit easier.

How n8n Cloud vs. Self-hosted n8n Works

n8n Cloud is a fully managed service. n8n hosts and maintains your instance — infrastructure, backups, some security measures, and so on.

Self-hosted n8n on a VPS or another type of server is your own instance: a container or bare metal setup, your database, your environment variables, your files.

You run n8n on your own server, and you’re responsible for:

n8n also points out that for self-hosted setups, encryption at rest is the responsibility of the hosting provider or the server owner, and TLS is typically handled via a reverse proxy.

What You Need to Take with You

Usually, you’ll want to bring:

Workflows

You can migrate n8n workflows as they are stored as JSON, so you can export and import them without issues.

The exported JSON includes credential names and credential IDs. The IDs themselves aren’t secret, but the names can be sensitive (for example, if you named a credential “prod-mastercard-api-key”).

Credentials

In self-hosted setups, credentials are stored in the database in encrypted form, and you need the encryption key to decrypt them.

In n8n Cloud, credentials can’t be exported, so you’ll need to recreate them.

Encryption Key

On first launch, n8n generates a random key and saves it to ~/.n8n, then uses it to encrypt credentials before writing them to the database. You can (and often should) set this explicitly via N8N_ENCRYPTION_KEY.

If you move the database or the data volume but change the key, your old credentials won’t be usable — which is exactly the kind of n8n credential issue that trips people up during an n8n server migration.

Your .n8n folder / Volume

In n8n’s Docker recommendations, they explicitly tell you to map a persistent volume to /home/node/.n8n so your data survives container restarts.

Even with PostgreSQL, persisting .n8n is still recommended because it contains important data (encryption keys, instance logs, etc.).

Database (SQLite or Postgres)

By default, n8n uses SQLite for credentials, workflows, and executions, but it also supports PostgreSQL via environment variables — so your n8n database migration plan depends on what you’re running.

External Dependencies

  • Deployment environment variables (URL, port, protocol, etc.)
  • Reverse proxy config (if you have one)
  • Custom/private nodes (if you used them)

Add execution history and the job queue to this list as well, if you need them.

Moving from n8n Cloud to Self-Hosted n8n

There are basically two migration scenarios: a targeted move and a full instance backup (an n8n workflow backup approach).

In theory, you could:

  1. Get a database dump from Cloud (but you’d need to coordinate that with n8n support, and there’s no guarantee they’ll hand it over as-is).
  2. Restore it into your self-hosted database.
  3. Bring n8n up and point it at that database.

But there are too many “ifs” here, and for a real-world n8n cloud migration, it’s usually more reliable to migrate n8n (and migrate n8n workflows) using the practical path instead. So let’s move on to the more realistic option.

Targeted Migration: Start with Docker

If you rented a clean server, start with Docker and installing n8n.

In your terminal, run the following commands, replacing <YOUR_TIMEZONE> with your timezone:

docker volume create n8n_data

docker run -it --rm \

--name n8n \

-p 5678:5678 \

-e GENERIC_TIMEZONE="<YOUR_TIMEZONE>" \

-e TZ="<YOUR_TIMEZONE>" \

-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \

-e N8N_RUNNERS_ENABLED=true \

-v n8n_data:/home/node/.n8n \

docker.n8n.io/n8nio/n8n

This command creates a volume for persistent data, pulls the required n8n image, and starts a container with the following settings:

  • Maps and exposes port 5678 on the host
  • Sets the container timezone
  • Enforces secure file permissions for the n8n settings file
  • Enables task runners for job execution in n8n
  • Mounts the n8n_data volume to /home/node/.n8n so your data survives container restarts

Open http://localhost:5678 to access n8n.

If You Prefer PostgreSQL

SQLite is used by default, but n8n can also run on PostgreSQL when configured via environment variables.

Use these commands if you want to run n8n on PostgreSQL. Replace the placeholders (in angle brackets, like <POSTGRES_USER>) with your values:

docker volume create n8n_data

docker run -it --rm \

--name n8n \

-p 5678:5678 \

-e GENERIC_TIMEZONE="<YOUR_TIMEZONE>" \

-e TZ="<YOUR_TIMEZONE>" \

-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \

-e N8N_RUNNERS_ENABLED=true \

-e DB_TYPE=postgresdb \

-e DB_POSTGRESDB_DATABASE=<POSTGRES_DATABASE> \

-e DB_POSTGRESDB_HOST=<POSTGRES_HOST> \

-e DB_POSTGRESDB_PORT=<POSTGRES_PORT> \

-e DB_POSTGRESDB_USER=<POSTGRES_USER> \

-e DB_POSTGRESDB_SCHEMA=<POSTGRES_SCHEMA> \

-e DB_POSTGRESDB_PASSWORD=<POSTGRES_PASSWORD> \

-v n8n_data:/home/node/.n8n \

docker.n8n.io/n8nio/n8n

The full Docker Compose file for PostgreSQL is available in the n8n hosting repository.

Updating n8n

Update n8n in Docker Desktop via the “Images” tab and choose “Pull” from the context menu to download the latest n8n image.

Or update via the command line.

Pull the latest (stable) version:

docker pull docker.n8n.io/n8nio/n8n

Pull a specific version:

docker pull docker.n8n.io/n8nio/n8n:1.81.0

Pull the next (unstable) version:

docker pull docker.n8n.io/n8nio/n8n:next

After pulling the updated image, stop the n8n container and restart it. You can do this from the command line as well.

First, find your container ID:

docker ps -a

Replace <container_id> in the commands below.

Stop the container:

docker stop <container_id>

Remove the container:

docker rm <container_id>

Start the container:

docker run --name=<container_name> [options] -d docker.n8n.io/n8nio/n8n

Updating Docker Compose

If you run n8n using a Docker Compose file, here are the steps to update:

Go to the directory that contains your Docker Compose file:

cd </path/to/your/compose/file/directory>

Pull the latest version:

docker compose pull

Stop and remove the old version:

docker compose down

Start the container:

docker compose up -d

You can skip this step if you’re using a VPS with n8n preinstalled.

Exporting Workflows from n8n Cloud

In the n8n Cloud UI:

  1. Open the workflow you need.
  2. In the menu, choose Export (or export from the workflows list).
  3. Save the JSON files to your local machine.

On self-hosted:

  1. Open your new n8n instance.
  2. Click Import and upload the JSON files.

This is basically how you export n8n workflows while moving only the critical automations.

What to Do About Credentials

Credentials can’t be exported from Cloud for security reasons, so you’ll need to recreate them manually — that’s the core pain point of n8n credential migration during an n8n cloud migration.

In Cloud, check which integrations each workflow uses (HTTP Request, Google Sheets, Telegram, Slack, etc.).

In self-hosted n8n, go to the Credentials section and create the same connections using the same keys. In each workflow, reassign the correct credentials.

Variables, Webhooks, and Proxies

If you use triggers (like GitHub, Stripe, Telegram, forms, or webhooks), you almost always have a reverse proxy and a public domain. In that case:

  • Set WEBHOOK_URL=https://your-domain/
  • Set N8N_PROXY_HOPS=1
  • Configure X-Forwarded-For/Host/Proto on the proxy

If you used or global variables, those are set on n8n’s side in Cloud. In a self-hosted setup, you’ll define them yourself in the container’s .env file or your Docker Compose configuration.

Test

Run your most critical workflows manually. Then verify that OAuth callback URLs and webhooks match the new domain.

Only after that should you update DNS and integrations to point to the new endpoint.

Migrating Between Self-Hosted Servers

Moving from one self-hosted server to another is easier than moving from Cloud. You can either move everything as-is (volume/DB) or export and import via the CLI. Both are common ways to migrate n8n hosting.

Option 1: Move the Instance Data

This works if you want the new instance to be as identical as possible.

  1. Stop n8n on the old server, which is essential for data consistency.
  2. Move your .n8n folder/volume (or whatever you set in N8N_USER_FOLDER) and the database (the SQLite file or a Postgres dump).
  3. On the new server, make sure .n8n is mounted as a persistent volume and that N8N_ENCRYPTION_KEY matches the old one (if you set it explicitly).
  4. Start n8n. Confirm credentials are available and your workflows run correctly.

This approach is essentially a full n8n server migration and avoids redoing the credential migration by keeping everything intact.

Option 2: Export and Import via the CLI

This is a better fit if you want to migrate n8n workflows and credentials, but not the entire instance state.

Export workflows

n8n export:workflow --all --output=backups/latest/workflows.json

# or separately

n8n export:workflow --backup --output=backups/latest/

Export credentials

n8n export:credentials --all --output=backups/latest/credentials.json

There’s a --decrypted flag that exports credentials in plain text. This can be useful if you’re doing an n8n credential migration to an instance with a different secret key, but it’s sensitive data — store and transfer that file as carefully as possible.

Import workflows

n8n import:workflow --input=workflows.json

# or import from a directory, if you exported separate files

n8n import:workflow --separate --input=backups/latest/

Import credentials

n8n import:credentials --input=credentials.json

n8n import:credentials --separate --input=backups/latest/

Then test as usual.

A Few Important Notes to Wrap Up

docs.n8n.io and support.n8n.io are the two resources that cover all the extra migration details. Or you can just reach out to is*hosting support right away if you’re moving to an n8n VPS. They can help you migrate n8n end to end.

If your webhook URL still points to the old domain, some triggers will simply stop coming in. And for reverse proxy setups, n8n has a dedicated guide with required environment variables and headers.

Even if you use Postgres, n8n recommends keeping .n8n as a persistent volume, because that’s where keys, logs, and other instance data live. This matters for both n8n workflow backup and n8n database migration reliability.

If you use --decrypted for credentials, you’re effectively dumping secrets. Always remember that all sensitive data will be visible in those files.

All that’s left is to test a few key workflows, and you can call the n8n migrate process done.