CALIBRATING SYSTEMS
Home / Blog / How to Update n8n Self Hosted Safely (and Back It Up First)
Tools

How to Update n8n Self Hosted Safely (and Back It Up First)

· 7 min read · Ali Raza Abro

Here is how to update n8n self hosted without drama: take a full backup (database, the .n8n folder with the encryption key, and an export of workflows and credentials), read the release notes for every version you are skipping, change the pinned image tag, then pull and restart with Docker Compose. If something breaks, you roll back the tag and restore the database. The update itself takes a couple of minutes. The backup is what makes it safe.

I look after n8n and Make setups for agencies, and the failures I get called in for are rarely about the update command. They are about a missing volume, a lost encryption key or a major version jump that nobody read the notes for. This guide covers the whole routine.

What you actually need to back up

A self-hosted n8n instance has three things that matter:

  1. The database. This holds workflows, credentials (encrypted), execution history, users and settings. On a basic install it is a SQLite file inside the .n8n folder. On a production install it should be Postgres.
  2. The encryption key. n8n uses it to encrypt credentials. It lives in the .n8n folder on the container's /home/node/.n8n path, unless you set N8N_ENCRYPTION_KEY as an environment variable. n8n's Docker docs note that this folder holds important data like encryption keys even when you use Postgres.
  3. Your config. The docker-compose file, the .env file and the reverse proxy config. Without these, rebuilding the server takes far longer than it should.

Lose the database and you lose everything. Lose the key and you keep your workflows but every credential has to be re-entered. Lose the config and you spend an afternoon reverse-engineering your own setup.

How to backup self hosted n8n

I use three layers, because each one protects against a different failure.

Layer 1: database dumps

For Postgres, run pg_dump nightly from a cron job on the host, against the Postgres container, and write a compressed file named with the date. Keep at least 14 days locally, then copy the files off the server to object storage such as S3, Backblaze B2 or Google Cloud Storage. A backup that lives on the same disk as the database does not survive a dead disk.

For SQLite, stop n8n briefly or use SQLite's own backup command before copying the file, so you do not copy it halfway through a write.

Layer 2: n8n workflow backup through the CLI

n8n's CLI can export workflows and credentials to JSON. The commands are export:workflow and export:credentials, run inside the container. Useful flags from the docs:

  • --all exports everything.
  • --separate writes one file per workflow, which is what you want for version control.
  • --backup is a shortcut for all, pretty and separate together.
  • --output sets the target file or folder.
  • --decrypted on credentials exports them as plain text. Only use this if the output goes straight into encrypted storage, and never commit it to Git.

A nightly export of workflows into a private Git repository gives you a readable history of every change. When someone breaks a workflow on Tuesday, you can see exactly what it looked like on Monday. Restoring uses import:workflow and import:credentials with --input.

Layer 3: server snapshots

If your host offers snapshots (DigitalOcean, Hetzner, AWS and most others do), take one right before every update. It is the fastest way back if an update goes badly wrong, but it is not a substitute for off-server backups.

Back up the key on its own

Copy the encryption key into your password manager or secrets store, labelled with the instance name. I recommend setting N8N_ENCRYPTION_KEY explicitly in your .env file so it is documented, rather than relying on the auto-generated one inside the volume.

How to update n8n self hosted on Docker Compose

This is the routine I follow. It assumes Docker Compose, which is what n8n's own docs now recommend over plain docker run.

  1. Check the current version. The pinned image tag in your compose file tells you, and the editor also shows the running version.
  2. Read the release notes for every version between your current one and the target. Look for breaking changes, removed environment variables, node changes and database migrations.
  3. Pause risky workflows if the instance handles payments or client-facing messages, or pick a quiet window.
  4. Take the backups: database dump, CLI export, server snapshot.
  5. Change the image tag in docker-compose.yml from the old version to the new one. Pin an exact version rather than using latest, so you always know what is running.
  6. Pull the new image with docker compose pull.
  7. Restart with docker compose down and then docker compose up -d. n8n runs any database migrations on startup.
  8. Watch the logs with docker compose logs until you see that the editor is accessible.
  9. Test by opening a few key workflows, running a manual execution, and triggering a real webhook.
  10. Check the executions list over the next hour for new errors.

If you run n8n in queue mode with workers, update the main instance and the workers to the same version at the same time. Mixed versions cause strange failures.

Why I pin versions instead of using latest

Using the latest tag feels convenient, but it means any restart, including an unplanned one after a server reboot, can pull a new version you never tested. Pinning means updates happen only when you choose. It also makes rollback trivial: you change the tag back.

The trade-off is that you must remember to update. I put a monthly reminder in ClickUp for each n8n instance I manage, with the checklist in the task description.

How to roll back a bad update

  1. Stop the stack with docker compose down.
  2. Change the image tag back to the previous version.
  3. If the new version ran database migrations, restore the database dump you took before the update. Older versions may not understand a migrated schema.
  4. Start the stack and test.
  5. Note what failed so you can fix it before trying again.

This is why the pre-update backup is non-negotiable. A rollback without a matching database backup can leave you worse off.

Major version jumps

Major versions of n8n can include breaking changes. The 1.0 release, for example, made user management mandatory and removed basic auth. When jumping a major version:

  • Read n8n's migration guide for that version.
  • Run n8n audit and fix warnings first.
  • Clone the instance to a staging server from your snapshot and test the upgrade there.
  • Check community nodes, which may not support the new version yet.

A simple maintenance schedule

  • Nightly: Postgres dump and workflow export, copied off-server.
  • Weekly: check that the latest backup file actually exists and is not empty.
  • Monthly: update n8n to the current stable release, run n8n audit, update the host OS.
  • Quarterly: do a test restore onto a blank server. A backup you have never restored is a guess.

I also send a Slack alert when the backup job fails. A simple n8n or Make workflow that checks the backup bucket for today's file and pings a channel if it is missing takes 15 minutes to build and has saved clients from finding out the hard way.

Common update problems

  • All credentials show errors after update. The container started without the original encryption key, usually because the volume was not mounted. Restore the volume or set the key.
  • Webhooks return 404. WEBHOOK_URL or the proxy config changed, or workflows were deactivated. Check that production workflows are active.
  • Editor will not load. Check logs for a failed migration. Roll back and read the release notes.
  • Community node errors. Update the community node or remove it before upgrading.

For more on locking down the instance itself, see my guide on how to secure n8n self hosted, and if you have not set up the stack yet, start with the n8n Docker setup guide.

How I build this

For agencies running self-hosted n8n, I set up the backup jobs, off-site storage, a failure alert in Slack and a written update runbook your team can follow. If an update has already gone wrong and workflows are down, Automation Rescue is built for exactly that: a fixed-price diagnosis and fix within 48 hours. Not sure where you stand? Request a free 15-minute Loom teardown and I will review your setup.

FAQ

How do I update n8n in Docker?

Back up first, change the image tag in docker-compose.yml to the new version, then run docker compose pull, docker compose down and docker compose up -d. Watch the logs and test key workflows afterwards.

How do I back up n8n workflows?

Use the CLI command export:workflow with the --backup flag and an --output folder, run inside the container. Commit the files to a private Git repo and keep separate database dumps too.

Will updating n8n delete my workflows?

Not if your data is on a persistent volume or in Postgres. Workflows are lost when the container is recreated without its volume, which is why backups and correct volume mounts matter.

Should I use the latest tag for n8n?

I do not recommend it for production. Pin an exact version so updates happen only when you plan them and rollback is just changing the tag back.

How often should I back up self-hosted n8n?

Nightly for the database and workflow export, plus a snapshot before every update. Test a full restore at least once a quarter.

Show me the workflow you hate.

Send one workflow and get a free 15-minute Loom teardown, or book a call if you’d rather talk it through.