n8n Environments with Git: Dev, Staging and Production
How to run n8n across dev, staging and production with Git source control: what each plan costs, how credentials and variables move, a Community-edition CLI pipeline, and the mistakes that break promotions.

Running n8n across development, staging, and production means connecting each instance to a Git repository and promoting work between branches, either with n8n's built-in source control or with a CLI pipeline you build yourself. The built-in feature works well, but it only exists on the Business plan ($800 a month, self-hosted) and above, so the real decision is whether that price beats assembling the same flow from the free CLI and API. This guide covers both paths: exact plan costs, setup steps, how credentials and variables travel, and the mistakes that break promotions.
What n8n environments actually are
n8n has two generations of this feature, and the naming is confusing.
Environments (Classic) is the Git-based source control most people mean when they search for this. Each n8n instance connects to a Git repository and checks out one branch. You build on a development instance, push its workflows to the dev branch, merge to main in your Git provider, then pull on the production instance. It is available on the Business and Enterprise plans.
Environments (the new version) is in preview and Enterprise-only. It replaces push and pull with a promote and apply model: you promote changes from one instance into an environment's Git branch, optionally route them through a promotion review for approval, and the target instance applies them. Promoting a workflow carries its dependencies along: credentials, variables, data tables, and tags. An instance runs one version or the other, never both, and n8n documents an upgrade path from Classic.
Two rules hold in both generations, and they shape everything else in this guide:
- Credential secrets are never written to the repository. What travels is a credential stub: name, type, and ID, with empty values.
- Executions and data table rows never travel either. The repo holds workflow definitions, tags, variables, and stubs, nothing else.
That first rule is a feature. Your Git provider never sees API keys, so a repo read token is not a breach of every connected system. It is also the main source of broken promotions, covered below.
What it costs
The pricing page is the honest starting point, because the feature gate decides your architecture:
- Starter, $20/month billed annually: no environments, no Git version control.
- Pro, $50/month billed annually: no environments either. Global variables yes, source control no.
- Business, $800/month billed annually: multiple environments and Git version control included. Self-hosted only; a cloud-hosted Business tier is waitlist-only at the time of writing. Includes 40,000 workflow executions a month, queue mode, and SSO/LDAP.
- Enterprise, custom pricing: hosted or self-hosted. The plan comparison lists two instances included (dev and prod), plus the new Environments preview, external secret stores, and log streaming.
- Community Edition, free: no environments feature at all. You build the pipeline yourself, covered in a later section.
Two details soften the Business price. First, the Startup plan gives companies under 20 employees 50% off Business, which puts environments at $400 a month. Second, one license key works on an unlimited number of instances, with combined usage counting toward your quota. So a dev instance, a staging instance, and a production instance share one Business license and one 40,000-execution pool.
A quick worked example. A 15-person automation team runs three self-hosted instances. Dev and staging consume almost no executions, production runs 28,000 a month. Combined they sit under the 40,000 quota, so the whole setup costs $9,600 a year on Business, or $4,800 with the startup discount. Compare that with the honest cost of the free path: the license costs nothing, but someone owns the CLI pipeline, its failure modes, and its documentation. If that ownership costs more than a few hours a month, the paid feature pays for itself. If your team already runs GitOps for everything else, the free path fits existing habits and the $9,600 stays in your pocket.
Setting up source control, step by step
This is the official setup flow with the sequencing that actually works. Do it on the development instance first.
- Create a dedicated repository. One repo for n8n source control, nothing else. Create the branches you need up front:
dev,staging,mainfor the classic three-environment setup. - Choose SSH or HTTPS. SSH uses a deploy key; n8n generates an ED25519 key by default and supports RSA if your Git host requires it. The deploy key must have write access, which is the step most people miss on GitHub, where deploy keys default to read-only. HTTPS uses a personal access token with repository read/write (Contents read/write on GitHub, source code pull/push on GitLab).
- Connect the instance. In n8n, go to Settings, then Environments, paste the repository URL, connect, and select the branch this instance tracks. Dev tracks
dev, staging tracksstaging, production tracksmain. - Protect production. On the production instance, enable Protected instance in the same settings screen. This blocks editing source-controlled resources on that instance, so hotfixes in prod become impossible and every change flows through the pipeline. Also set a distinct instance color; it shows next to the push and pull buttons and prevents the classic "I edited the wrong instance" incident.
- Decide who can push and pull. Instance owners and admins can push and pull. Project admins can push but not pull. Plan your roles around that: the people building in dev need push; almost nobody needs pull anywhere except production.
- Private certificate authorities. If your Git host uses a private CA (common with self-hosted GitLab inside a VPC), set
GIT_SSL_CAINFOto a PEM file orGIT_SSL_CAPATHto a certificate directory on the n8n instance. Git uses its own trust store, so n8n's general custom-CA configuration does not apply here. This requires n8n 2.40.0 or later.
One structural recommendation from the push and pull documentation: keep each instance one-directional. Dev pushes, production pulls. An instance that does both is where merge conflicts and overwritten work come from.
Also know the limit: n8n's source control is not full Git. There is no pull-request review flow inside n8n. If you want four-eyes review before production, do it in GitHub or GitLab on the merge from dev to main, which is exactly where it belongs anyway.
The daily promotion flow
Once connected, the rhythm is simple. Build in dev, push, merge in your Git provider, pull in staging or production. The details that matter:
Auto publish on pull. Pulling a workflow does not automatically make it live. The pull modal has an Auto publish dropdown with three modes: Off (the default, workflows keep their current publish state), "If workflow already published" (only re-publish workflows that are already live), and On (publish everything pulled, including new workflows). For production, "If workflow already published" is usually right: updates to live workflows go live, but a brand-new workflow arrives unpublished until a human activates it. Archived workflows are never auto-published regardless of the setting. After the pull, n8n shows which workflows published and which failed, with reasons.
Deletions are never automatic. If a workflow is deleted from the repo, pulling does not delete it locally. n8n flags it as outdated and asks. This is deliberately conservative and occasionally annoying; build the cleanup confirmation into your release checklist.
Ownership follows email and project ID. On pull, n8n tries to match the workflow owner by email address; if no match exists, the user performing the pull becomes the owner. Project-owned workflows match by project ID, and n8n creates the project if it is missing. Keep user emails consistent across instances or your ownership map will quietly scramble.
Credentials and variables across environments
This is where promotions actually succeed or fail.
Because only credential stubs travel, a freshly pulled workflow has credentials with no values. n8n tells you which stubs need populating after a pull. Someone must enter the real values once per instance, manually or through an external secret store. Enterprise plans include external secret store integration (Vault, AWS Secrets Manager, and similar), which removes the manual step by resolving secrets at runtime.
The design decision to make up front: same credential names, different values per environment. Your dev instance has a credential named "Postgres - orders" pointing at the dev database; production has a credential with the same name pointing at the production database. Workflows reference the credential, not the connection details, so the same workflow JSON runs against the right system in each place.
Variables behave differently from credentials, and the difference bites people. Variable stubs travel on Classic source control, but in the new Environments model variables travel with their values. Do not put environment-specific endpoints in variables that promote; put them in credentials or in instance-level environment configuration instead. Use variables for values that are genuinely the same everywhere.
A practical checklist for each new workflow before it leaves dev:
- All connections use named credentials, never hardcoded URLs or tokens in node fields.
- Every credential exists, by the same name, on the target instance, with values populated.
- Environment-specific configuration lives in credentials, not in variables or Code nodes.
- Webhook paths do not collide with existing paths on the target instance (publish checks catch this, but only at publish time).
Automating promotion with the API
Everything the push and pull buttons do is available in the public API, which means promotion can live in your CI/CD pipeline instead of in someone's clicking finger. The status and push endpoints exist from n8n version 2.39.0.
Three endpoints matter:
GET /api/v1/source-control/statuspreviews pending changes in either direction. It is the same file list the UI shows in the push and pull modals.POST /api/v1/source-control/pushcommits and pushes, but requires afileNamesarray. You cannot push blind; callstatusfirst and build the array from what it returns.POST /api/v1/source-control/pullfetches the connected branch into the instance.
A production deploy step in a pipeline looks like this:
curl -X POST "https://n8n-prod.example.com/api/v1/source-control/pull" \
-H "X-N8N-API-KEY: $N8N_PROD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"force": true}'
On Enterprise plans, API keys support scopes: sourceControl:pull, sourceControl:push, and sourceControl:read. Use them to enforce direction. The production instance's key gets sourceControl:pull and sourceControl:read only, so a leaked prod key can never push, and a CI job can preview with status before pulling. That is a genuinely useful governance property for regulated environments: the production instance is technically incapable of originating changes. If the workflows you are promoting orchestrate AI agents, the same one-directional discipline applies there too; our guide to AI agent orchestration best practices covers the agent-side patterns.
The Community Edition path: build the pipeline yourself
Community Edition, the free, fair-code version you self-host from the n8n GitHub repository under the Sustainable Use License, has no source control feature. But it has a full server CLI, and that is enough to assemble a serviceable GitOps flow. The ingredients:
Export from dev, one file per workflow:
docker exec -u node -it n8n-dev \
n8n export:workflow --all --separate --output=/backups/dev/
The --separate flag writes one JSON file per workflow, which is what makes Git diffs readable. Commit that directory to your repo and review changes there. For releases, --published exports only the currently published version of each workflow, which is closer to "what should production run" than the working draft.
Import on production with the matching import:workflow command, then publish what should be live:
docker exec -u node -it n8n-prod \
n8n publish:workflow --id=<WORKFLOW_ID>
A note on versions: in n8n 2.0 the old active/inactive toggle became a publish/unpublish model. publish:workflow runs the same validation as publishing from the editor, including webhook path conflict checks, and it deliberately has no --all flag, to prevent accidental bulk publishing in production. With the default publication service enabled, a running instance picks up CLI publish changes within about 15 seconds.
Credentials are the hard part, exactly as in the paid feature, except worse: there is no stub mechanism in a raw export. export:credentials --all exports encrypted credentials; --decrypted exports plaintext and the docs warn that all sensitive information is visible in the output. Treat decrypted exports as secrets: encrypted at rest, never in the repo, transferred out of band. Most teams on this path end up recreating credentials by hand per instance and keeping only workflows in Git. That is fine. It is the same discipline the paid feature enforces.
What you give up versus Business: no UI diff view, no protected-instance guard, no auto publish on pull, no ownership matching, and no scoped API enforcement. You rebuild each of those with process and discipline. For a two-person team with strong Git habits, that trade is reasonable. For a team where five people edit workflows, the paid feature is cheaper than the incidents. If the self-hosted route appeals but you do not want to own the servers, backups, and upgrades around it, that is the gap our managed open-source stack service exists to fill.
When environments are the wrong choice
- Solo builder, handful of workflows. If one person edits everything and breakage costs an hour, the overhead of three instances exceeds the risk it removes. Use workflow history and the built-in versioning instead.
- Workflows that are mostly state, not logic. If the valuable thing is the credential configuration and the workflow JSON is trivial, source control protects the wrong asset.
- You need approval gates but you are on Business. Promotion reviews are Enterprise-only in the new Environments. On Business, the review has to happen as a Git provider merge requirement, which works, but if auditors need the approval recorded inside the automation platform, that is an Enterprise conversation.
- Heavy data tables usage. Data table rows never travel. If your workflows depend on seeded reference data in data tables, you need a separate migration story for that data, and environments will not provide it.
Common mistakes
- Deploy key without write access. GitHub deploy keys are read-only by default. The connect step succeeds and the first push fails. Enable write when creating the key.
- Editing production directly. One emergency hotfix on prod, forgotten, then overwritten by the next pull. Protected instance exists precisely for this; turn it on.
- Push and pull on the same instance. n8n explicitly recommends against it. Bidirectional instances are where conflicts breed.
- Environment-specific values in variables. Variables promote with their values in the new Environments model. A variable holding the dev API base URL will cheerfully overwrite production's.
- Forgetting credential stubs after a pull. The workflow imports cleanly, publishes cleanly, then fails at 2 a.m. because the Slack credential has no token. Populate stubs the same day as the pull.
- Expecting deletions to sync. They do not. Deleting in dev and pushing leaves the production copy in place until someone confirms the removal.
- Treating the repo as a backup. It is close, but it has no credential values, no executions, and no data table rows. Keep real backups too.
Frequently asked questions
Is n8n source control available on the free Community Edition?
No. Git-based environments require the Business plan ($800/month annually, self-hosted) or Enterprise. On Community Edition you can approximate the flow with the CLI: export:workflow --all --separate into a Git repo, then import:workflow plus publish:workflow on the target instance.
Do my credentials get committed to Git? No. n8n commits credential stubs containing the name, type, and ID, never the secret values. After pulling to a new instance you populate the values once, manually or via an external secret store on Enterprise.
Can I get approval before changes reach production? Yes, two ways. In the new Enterprise Environments, promotion reviews add an approval step inside n8n. On the Classic feature, enforce review as a merge requirement on the production branch in GitHub or GitLab, since n8n itself has no pull-request flow.
How many instances does one Business license cover? Unlimited. A single license key applies to as many instances as you run, and their combined executions count toward the shared quota (40,000 a month at the base Business tier).
What happens to published workflows when I pull? Pulling overwrites the local workflow definitions with the repo versions, and the Auto publish setting controls whether pulled workflows become the live published version: Off, only if already published, or always on. After the pull, n8n shows a results modal listing which workflows published and which failed, with reasons.
Should dev and production share one n8n instance with projects instead? For genuinely tiny setups, projects give you separation without a second instance, but there is no promotion mechanism between projects, so "release" means copy-paste. Once more than one person edits workflows, separate instances with source control are the safer answer.
Where to go from here
Pick the path that matches your team: Business plan source control if several people touch workflows and you want guardrails in the UI, or the CLI pipeline if you are small, technical, and already live in Git. Either way, protect production, keep secrets out of the repo, and make promotion one-directional. We deploy and operate n8n and the rest of the managed open-source stack for teams that want this running without owning the plumbing, and our business automation service covers exactly this kind of environment design. If you are weighing self-hosted n8n against the rest of your stack, our guides on production AI deployment strategies and monitoring and observability for AI agents cover the surrounding pieces.
Related reading
About AI Agents Plus Editorial
AI automation expert and thought leader in business transformation through artificial intelligence.



