Your stack, your burden
Self-host on EU infrastructure when CRM or personal data must stay on systems you control and you have someone to patch and back it up. For self-hosted n8n, n8n GmbH is neither data controller nor data processor; you own retention, deletion and every data subject request. If you do not need that level of control, n8n Cloud with its DPA is the simpler default.
n8n sits in the middle of the revenue stack. It connects the CRM, the enrichment tool, the sequencer, the LLM and whatever webhook the team invented last quarter. When the data flowing through those workflows includes personal data, specifically CRM contact records, enrichment payloads from Clay or Apollo, and anything an AI node processes, the question of where n8n runs stops being an infrastructure preference and becomes a GDPR decision.
We build n8n workflows for B2B revenue teams and covered the full automation stack in the n8n for RevOps guide. This post is the setup and hardening guide for the specific case: self-hosting n8n in the EU so that CRM and revenue data stays on infrastructure you control.
Self-hosted or n8n Cloud: what actually changes under GDPR
The distinction comes down to who carries which GDPR obligation.
When you self-host, you become the controller (or remain the processor if you operate on behalf of another controller) for everything that passes through the instance. There is no contract with n8n GmbH that covers data processing because n8n GmbH never sees your data. That is the whole point, and the whole burden.
Under GDPR Article 30, the controller must maintain records of processing activities. Under Article 32, you must implement appropriate technical and organisational security measures. Under Chapter V, transfers to third countries require an adequacy decision, standard contractual clauses, or another legal basis (GDPR full text, eur-lex.europa.eu). Self-hosting moves these obligations from a vendor you can lean on to a team that must deliver them. This isn't legal advice.
Where revenue data leaks out of an "EU" n8n
Hosting n8n on a Hetzner box in Falkenstein does not mean your data stays in Falkenstein. Every node in a workflow that calls an external service sends data to that service's infrastructure. For revenue workflows, that usually means:
- CRM APIs. Where your CRM data sits depends on the account's hosting region. HubSpot accounts can be hosted in the EU (Germany), and data for those accounts is processed and stored there (HubSpot data hosting FAQ). If your account is US-hosted, every read or write from the n8n HubSpot node sends data across the Atlantic. Check your account's data hosting location before assuming a cross-border transfer.
- Enrichment services. Clay and Apollo: the enrichment call sends an email or domain out and gets personal data back. Both directions are transfers.
- LLM providers. The OpenAI node, the Anthropic node, or any HTTP Request node calling an inference API sends whatever you put in the prompt. If that prompt contains a contact name, a company, a deal value, that is personal data leaving the EU.
- Webhook endpoints. A workflow that posts to Slack, sends an error notification to an email service, or pushes to a Google Sheet is sending data wherever those services are hosted.
- Community nodes. Third-party nodes from the n8n community can make network calls. n8n's own security guidance warns that community nodes are not vetted and you should review their code before installing them (n8n security docs).
- Telemetry. By default, self-hosted n8n sends usage telemetry to n8n GmbH. n8n states it does not collect the data that flows through your workflows, and it does not collect your credentials. It does collect instance configuration, pseudonymous identifiers, product usage patterns, and the registrable domains of HTTP Request and webhook addresses. Disable it by setting
N8N_DIAGNOSTICS_ENABLED=false. To also disable version checks and template fetches, setN8N_VERSION_NOTIFICATIONS_ENABLED=falseandN8N_TEMPLATES_ENABLED=false(n8n privacy docs). Note: with a paid licence, your instance continues to report usage counts and your licence identifier regardless of the telemetry setting.
The practical step is to build a destination inventory for every workflow that handles personal data. List each node, note where the service is hosted, and record the legal basis for the transfer. If you are already running GDPR opt-out syncs across your stack, this is the same exercise extended to the orchestration layer.
For the webhook handoff between Clay, n8n and HubSpot specifically, we covered the data flow in the Clay to n8n to HubSpot webhook guide.
The production setup for CRM data
n8n's documentation covers several deployment options: Docker Compose, Kubernetes, and various cloud providers including Hetzner (n8n hosting docs). For most RevOps teams running a single instance, Docker Compose with an external PostgreSQL database is the documented starting point.
Here is a minimal .env configuration using only documented environment variables. Every value marked CHANGE_ME is a placeholder you must replace. Do not commit real secrets to version control.
# --- Database ---
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=CHANGE_ME_DB_PASSWORD
# --- Encryption ---
# Back this key up. Without it you cannot decrypt stored credentials.
N8N_ENCRYPTION_KEY=CHANGE_ME_GENERATE_A_RANDOM_STRING
# --- Execution data retention ---
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168
# --- Telemetry opt-out ---
N8N_DIAGNOSTICS_ENABLED=false
# --- Security hardening ---
NODES_EXCLUDE=["n8n-nodes-base.executeCommand","n8n-nodes-base.localFileTrigger","n8n-nodes-base.ssh"]
N8N_BLOCK_ENV_ACCESS_IN_NODE=true
A few things about this configuration:
N8N_ENCRYPTION_KEY is used to encrypt credentials in the n8n database (n8n deployment env vars). If you do not set it, n8n creates a random key on first start and stores it in the N8N_USER_FOLDER directory (.n8n by default). If you lose the key, every credential in the database becomes unreadable. Store it in a secrets manager (AWS Secrets Manager, HashiCorp Vault, or at minimum an encrypted note outside the server) and include it in your backup procedure.
Reverse proxy with TLS. n8n should sit behind a reverse proxy (Nginx, Caddy, Traefik) that terminates TLS. Do not expose n8n directly to the internet over plain HTTP. n8n's own security documentation recommends this setup (n8n security docs).
PostgreSQL over SQLite. The default embedded database is SQLite. For anything beyond a test instance, use PostgreSQL. It handles concurrent access, makes backups straightforward, and is what the Docker Compose production guides use.
Without a license key, n8n runs as the Community Edition under the Sustainable Use License. This permits commercial use. Business and Enterprise features, including SSO, role-based access control and multiple environments, require a paid license key purchased through n8n (n8n hosting docs).
Execution data retention: the setting that answers most deletion requests
Every time a workflow runs, n8n stores the execution data: the input and output of every node, including whatever personal data the workflow processed. If a workflow enriches a contact through Clay and writes the result to HubSpot, the execution log contains the full enrichment payload. That is the data that accumulates and that GDPR requires you to control.
The environment variables that govern retention:
EXECUTIONS_DATA_PRUNE: boolean, defaulttrue. Enables automatic deletion of old executions. Even though the default is on, set it explicitly so the intent is documented (n8n execution env vars).EXECUTIONS_DATA_MAX_AGE: number of hours to keep executions. Default is336(14 days). The n8n privacy documentation recommends pruning "every few days" (n8n privacy docs). A value of168(seven days) keeps enough history to debug recent failures without accumulating weeks of personal data. Choose based on your retention policy.EXECUTIONS_DATA_PRUNE_MAX_COUNT: maximum number of executions to keep. Default is10000. Works alongsideMAX_AGE; whichever limit is reached first triggers deletion.EXECUTIONS_DATA_SAVE_ON_SUCCESS:allornone, defaultall. Set tononeto stop storing execution data for successful runs entirely. This is the most aggressive retention posture: you keep data only for runs that failed, which is what you need for debugging. Set toallif you need an audit trail.EXECUTIONS_DATA_SAVE_ON_ERROR:allornone, defaultall. Controls whether failed executions are saved. Keep this atallunless you have a reason not to; failed executions are where you find the bugs.
When a data subject requests deletion, you need to find and delete any executions that contain their data. n8n's execution list can be filtered, and individual executions can be deleted from the UI or through the API. If you have set EXECUTIONS_DATA_PRUNE=true with a short EXECUTIONS_DATA_MAX_AGE, most requests are already handled by the time they arrive: the data has been pruned.
The execution log is the largest store of personal data in n8n, and these variables control its lifecycle.
Lock it down
Once the instance is running, harden it. n8n's security documentation covers several measures (n8n security docs):
Run the security audit. n8n includes a built-in security audit you can trigger from the CLI (n8n audit), the API, or an n8n node inside a workflow. It generates five reports covering credentials, database, file system, nodes and instance configuration (n8n security audit docs). Run it after setup and after each configuration change.
Exclude risky nodes. The NODES_EXCLUDE environment variable blocks specific nodes from the editor. The default excludes n8n-nodes-base.executeCommand and n8n-nodes-base.localFileTrigger (n8n nodes env vars). Setting NODES_EXCLUDE replaces the default list, so your value must include the defaults plus any additions. The .env block above keeps both defaults and adds n8n-nodes-base.ssh, which opens SSH connections from the n8n server.
Block environment variable access. Set N8N_BLOCK_ENV_ACCESS_IN_NODE=true to prevent the Code node and expressions from reading server environment variables (n8n security env vars). The default is false. Without this, anyone who can edit a workflow can read your database password and encryption key from the n8n process environment.
Community nodes policy. Community nodes are npm packages that can execute arbitrary code and make arbitrary network requests. n8n's documentation warns about the risks of installing community nodes (n8n security docs). Community node installation is enabled by default (N8N_COMMUNITY_PACKAGES_ENABLED=true). For a production instance handling personal data, set it to false or review every package before installing it.
User roles and SSO. SSO and LDAP are available on Business (self-hosted) and Enterprise editions. Audit logging and custom roles require Enterprise (n8n.io/pricing). If multiple people access the instance, check which plan covers the access controls you need.
Disable telemetry. Already covered above: N8N_DIAGNOSTICS_ENABLED=false.
Backups, updates and who owns them
Self-hosting means you own the failure mode. When something breaks, your team fixes it.
Database backups. Back up the PostgreSQL database on a schedule. pg_dump to a compressed file, encrypted, stored off-server. Test restores regularly, not just the dump.
Encryption key. Back up N8N_ENCRYPTION_KEY separately from the database. If you restore the database without the key, every stored credential is unrecoverable. If you restore the key without the database, there is nothing to decrypt. Both must be recoverable together.
Update cadence. n8n releases frequently. Each release may include security patches. Subscribe to release notifications and apply updates on a regular schedule, not when something breaks. The update process for Docker Compose is pulling the new image and restarting; test it on a staging instance first.
The real cost. The server itself is cheap. The expensive part is the person who patches, monitors, backs up and restores. That is the decision: is that person on your team, or do you want n8n Cloud to be that person? For the cost comparison between in-house and on-demand RevOps resources, see the RevOps salary vs on-demand team cost analysis.
A ten-point checklist before you route CRM data through it
- Deploy in an EU region with a host that signs a DPA with you.
- Set
N8N_ENCRYPTION_KEYexplicitly and store it in a secrets manager. - Put n8n behind a reverse proxy with TLS. No plain HTTP.
- Use PostgreSQL, not SQLite.
- Set
EXECUTIONS_DATA_PRUNE=trueand choose anEXECUTIONS_DATA_MAX_AGEthat matches your retention policy. - Set
N8N_DIAGNOSTICS_ENABLED=falseto disable telemetry. - Exclude risky nodes with
NODES_EXCLUDEand setN8N_BLOCK_ENV_ACCESS_IN_NODE=true. - Build a destination inventory: for every workflow handling personal data, list each external node and where it sends data.
- Set up database backups, test restores, and store the encryption key separately.
- Document this setup in your Article 30 records of processing activities.
FAQ
Is self-hosted n8n GDPR compliant?
Self-hosted n8n is infrastructure, not a compliance certificate. GDPR compliance depends on how you configure it, where you host it, how you handle execution data retention, and what you do about the external services each workflow node calls. n8n's privacy documentation states that for self-hosted deployments, n8n GmbH is neither controller nor processor of the data in your workflows (n8n privacy docs). The compliance obligation sits entirely with you.
Is n8n Cloud hosted in the EU?
As of November 2026, n8n Cloud stores data in the EU with servers in Frankfurt, Germany (n8n.io/pricing). Check the pricing page for the current plans and any changes to hosting regions. The Cloud DPA is included in the standard Terms of Service and includes Standard Contractual Clauses.
Do I need a DPA if I self-host n8n?
Not with n8n GmbH, because they are not processing your data. You do need DPAs with every external service your workflows call: your CRM provider, your enrichment provider, your LLM provider, your email service. The DPA question shifts from one vendor (n8n) to many (every node destination).
How long does n8n keep execution data?
On self-hosted n8n, as long as you let it. With EXECUTIONS_DATA_PRUNE=true and EXECUTIONS_DATA_MAX_AGE set, n8n automatically deletes executions older than the specified number of hours. Without pruning enabled, execution data accumulates indefinitely. On n8n Cloud, the retention policy is governed by the DPA and the plan terms.
Can I use OpenAI or Claude nodes and stay GDPR compliant?
Using an LLM node sends whatever is in the prompt to the provider's API. If the prompt contains personal data (a contact name, an email, a deal value), that is a data transfer to the provider's infrastructure, which may be outside the EU. Compliance requires a legal basis for that transfer (the provider's DPA, standard contractual clauses, or an adequacy decision), and the data minimisation principle applies: send only what the task requires. There is no blanket yes or no. For the broader compliance picture on outbound data, see the GDPR cold email compliance guide.
Is the self-hosted Community Edition free for commercial use?
n8n's Community Edition is available under the Sustainable Use License, Version 1.0. The license states: "You may use or modify the software only for your own internal business purposes or for non-commercial or personal use" (n8n LICENSE.md on GitHub). This permits running it commercially for your own business. The Sustainable Use License is not OSI-approved open source; distributing n8n or offering it as a managed service to third parties is restricted. Features n8n marks as Enterprise require a separate paid license.
If your revenue workflows carry personal data and you need the setup done right, not just running but hardened, documented and backed up, we can help.