Skip to content
Guides

n8n environment variables for production: what to set and why

The n8n environment variables worth setting on a production instance: URLs, encryption key, Postgres, timeouts, logging, and the security defaults in 2.x.

By then8nblog Editors7 min read
Tested on n8n 2.46.7intermediate
Illustration of n8n production environment variables: public URLs and proxy hops, a fixed encryption key, Postgres instead of SQLite, execution timeouts and JSON logs

On a production n8n instance, set at least these environment variables yourself: the public URLs (N8N_HOST, N8N_PROTOCOL, N8N_WEBHOOK_URL, and N8N_PROXY_HOPS behind a reverse proxy), a fixed N8N_ENCRYPTION_KEY that you back up, GENERIC_TIMEZONE, and the DB_* variables for Postgres. After that, the ones that save you later are an execution timeout, pruning limits that fit your disk, and JSON logs. n8n 2.x already ships safer security defaults, so most hardening is about not undoing them.

The short version:

VariableDefaultSet it to
N8N_HOST, N8N_PROTOCOLlocalhost, httpYour domain and https
N8N_WEBHOOK_URLemptyhttps://<your-domain>/ behind a reverse proxy
N8N_PROXY_HOPS0The number of proxies in front of n8n, usually 1
N8N_ENCRYPTION_KEYgenerated on first startA long random string you store safely
GENERIC_TIMEZONEAmerica/New_YorkYour timezone, for example Europe/Berlin
DB_TYPEsqlitepostgresdb, plus the DB_POSTGRESDB_* variables
EXECUTIONS_TIMEOUT-1 (no timeout)A ceiling in seconds, for example 3600
N8N_LOG_FORMATtextjson if a log system reads the logs

Defaults come from n8n's environment variable reference and the config source at 2.46.7, the stable release when we checked on November 10, 2026. Where the two disagree, this guide says so and follows the source.

What we checked on n8n 2.46.7

We started n8n 2.46.7 locally with a test set of these variables and read its startup log:

  • WEBHOOK_URL (the old name) still worked, and n8n logged a deprecation notice at startup: "WEBHOOK_URL -> Use N8N_WEBHOOK_URL instead".
  • N8N_ENCRYPTION_KEY_FILE pointing at a file with a trailing newline: n8n printed "The file specified by N8N_ENCRYPTION_KEY_FILE contained leading or trailing whitespace; the value was trimmed", and wrote the trimmed key to .n8n/config, which it created with 0600 permissions.
  • N8N_LOG_FORMAT=json turned every log line into a JSON object with level, message and metadata.
  • N8N_METRICS=true made /metrics return Prometheus metrics (lines starting with n8n_), and /healthz answered {"status":"ok"}.
  • N8N_BLOCK_ENV_ACCESS_IN_NODE left unset: a workflow with the expression {{ $env.HOME }} failed with "access to env vars denied". With the variable set to false, the same workflow succeeded.

Where to set them

With Docker Compose, put them under the n8n service's environment: key, or in an .env file that Compose reads. After a change, recreate the container (docker compose up -d) so the new values take effect. Our Docker Compose guide builds a complete stack with Postgres, Caddy and task runners.

For secrets, append _FILE to the variable name and point it at a file, such as a Docker or Kubernetes secret. n8n's configuration docs say most variables accept the suffix, with credentials and database settings the most useful. In the 2.46.7 source, n8n's config loader checks <NAME>_FILE for every variable it defines, and a source comment names N8N_ENCRYPTION_KEY_FILE explicitly. Two exceptions we know of:

  • The task runner image doesn't read _FILE variables, per the task runner reference. Pass the runner token as a normal variable.
  • Variables that n8n reads straight from the process environment rather than through its config loader, such as N8N_BLOCK_ENV_ACCESS_IN_NODE, don't get the _FILE treatment.

URLs and the reverse proxy

These decide which URLs n8n shows in the editor and registers for webhooks. Get them wrong and webhook URLs point at localhost or plain http.

  • N8N_HOST (default localhost) and N8N_PROTOCOL (default http): the host name and protocol people use to reach n8n.
  • N8N_WEBHOOK_URL: the public base URL for test and production webhooks behind a reverse proxy. The old name WEBHOOK_URL is deprecated from n8n 2.35.0; the endpoints reference says it still works but logs a deprecation warning at startup.
  • N8N_PROXY_HOPS (default 0): the number of reverse proxies in front of n8n. n8n's reverse proxy guide sets it to 1 and has the last proxy pass X-Forwarded-For and the other forwarded headers.
  • N8N_EDITOR_BASE_URL: the public editor URL, also used in emails n8n sends and as the SAML redirect URL. Set it when emails or SSO are in use.
  • N8N_PATH (default /): the deployment reference warns that a sub-path behind a reverse proxy can cause folder navigation issues, and suggests a subdomain instead.

Our webhooks guide shows what goes wrong with test and production URLs when these are off.

The encryption key

n8n encrypts every credential in the database with N8N_ENCRYPTION_KEY. If you don't set it, n8n generates a random key on first launch and saves it in the .n8n folder. That works until the folder is lost: a new container without that volume, a restore to a new server, or a second instance. Without the original key, the stored credentials can't be decrypted.

Set it yourself, keep a copy outside the server, and use the same value everywhere the database is used. The docs say every queue mode worker needs it too (see our queue mode guide). The docs describe the variable for an instance whose settings file doesn't hold a key yet. On an instance that already runs, take the existing key from the .n8n/config file and set that value, rather than a new one.

# Generate a key once and store it somewhere safe
openssl rand -hex 32

The database: Postgres instead of SQLite

DB_TYPE defaults to sqlite. For production, n8n's database reference covers Postgres with these variables (defaults in brackets):

  • DB_TYPE=postgresdb
  • DB_POSTGRESDB_HOST (localhost), DB_POSTGRESDB_PORT (5432), DB_POSTGRESDB_DATABASE (n8n), DB_POSTGRESDB_USER (postgres), DB_POSTGRESDB_SCHEMA (public)
  • DB_POSTGRESDB_PASSWORD, or better DB_POSTGRESDB_PASSWORD_FILE
  • DB_POSTGRESDB_POOL_SIZE (2): parallel connections. The docs say raising it may help, but too many connections can hurt performance.

If you stay on SQLite for a small instance, its data lives in the same .n8n folder as the encryption key, so that volume is the whole instance.

Executions: timeouts, pruning and concurrency

From the executions reference, matched against the 2.46.7 source:

VariableDefaultWhat it does
EXECUTIONS_TIMEOUT-1Default timeout in seconds for every workflow; -1 means none, so a run that hangs keeps going until someone stops it.
EXECUTIONS_TIMEOUT_MAX3600The highest timeout a user can set on a single workflow.
EXECUTIONS_DATA_PRUNEtrueDeletes old execution data on a rolling basis.
EXECUTIONS_DATA_MAX_AGE336Hours to keep executions (14 days).
EXECUTIONS_DATA_PRUNE_MAX_COUNT10000Maximum executions kept; 0 means no limit.
EXECUTIONS_DATA_SAVE_ON_SUCCESS, EXECUTIONS_DATA_SAVE_ON_ERRORall, allSet success to none to store only failed runs.
N8N_CONCURRENCY_PRODUCTION_LIMIT-1Maximum production executions running at once; -1 disables the limit in regular mode.

A timeout is the one most instances are missing. Pick a ceiling that's longer than your slowest legitimate workflow; individual workflows can still set their own timeout up to EXECUTIONS_TIMEOUT_MAX. For pruning in depth, including how to free disk space on SQLite, see prune n8n execution data.

Security: defaults that are already on in 2.x

n8n 2.0 changed several security defaults, according to its 2.0 breaking changes. The 2.46.7 source matches the breaking-changes page. The security reference page still lists the older defaults for some of them (checked November 10, 2026), so don't copy values from that table without checking.

VariableDefault in 2.xWhat it means
N8N_BLOCK_ENV_ACCESS_IN_NODEtrueExpressions and the Code node can't read environment variables. In the source, access is blocked unless the variable is exactly false.
N8N_RESTRICT_FILE_ACCESS_TO~/.n8n-filesThe Read/Write Files from Disk and Read Binary Files nodes only reach this folder.
N8N_BLOCK_FILE_ACCESS_TO_N8N_FILEStrueBlocks file nodes from the .n8n folder, where the encryption key lives.
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONStruen8n requires 0600 permissions on its settings file. The docs say to set it to false only where file permissions aren't supported, such as Windows.
N8N_GIT_NODE_DISABLE_BARE_REPOStrueThe Git node refuses bare repositories.
N8N_SECURE_COOKIEtrueThe login cookie is only sent over HTTPS.

If a workflow fails with access to env vars denied, that's N8N_BLOCK_ENV_ACCESS_IN_NODE doing its job. The 2.0 breaking changes suggest credentials or other secure methods for sensitive values rather than turning env access back on.

The safe move is to leave these alone. Don't set N8N_SECURE_COOKIE=false to make plain-HTTP access work on a public server; put n8n behind HTTPS instead.

Two settings that are off by default and worth considering:

  • N8N_SSRF_PROTECTION_ENABLED (default false): guards outbound requests whose destination comes from user input against internal targets such as localhost, private network ranges and the cloud metadata address 169.254.169.254, with allow and block lists for hosts and IP ranges, per the SSRF protection reference. Worth turning on when workflows build URLs from data that outsiders control.
  • N8N_PUBLIC_API_DISABLED (default false): turns off n8n's public REST API if you don't use it.

Logging and monitoring

From the logs reference and the endpoints reference:

  • N8N_LOG_LEVEL (info): error, warn, info or debug. Use debug only while troubleshooting.
  • N8N_LOG_FORMAT (text): json prints one JSON object per line with the message, level, timestamp and metadata, which log collectors parse without extra rules.
  • N8N_LOG_OUTPUT (console): console, file or both, comma-separated.
  • N8N_METRICS (false): turns on the Prometheus /metrics endpoint.
  • N8N_ENDPOINT_HEALTH (healthz): the path of the health check endpoint that uptime monitors and container health checks call.

Optional: telemetry, notifications and shutdown

  • N8N_DIAGNOSTICS_ENABLED (true): shares anonymous telemetry with n8n. The deployment reference notes that with it set to false, you can't enable Ask AI in the Code node.
  • N8N_VERSION_NOTIFICATIONS_ENABLED (true): shows notifications about new versions and security updates. Leave it on unless another process tells you about releases.
  • N8N_GRACEFUL_SHUTDOWN_TIMEOUT (30): seconds n8n waits for components to shut down before the process exits.

A production environment block

Putting it together for the n8n service in Docker Compose. Replace the placeholders, and keep the secrets in files:

services:
  n8n:
    environment:
      N8N_HOST: n8n.example.com
      N8N_PROTOCOL: https
      N8N_WEBHOOK_URL: https://n8n.example.com/
      N8N_PROXY_HOPS: 1
      N8N_ENCRYPTION_KEY_FILE: /run/secrets/n8n_encryption_key
      GENERIC_TIMEZONE: Europe/Berlin
      TZ: Europe/Berlin
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD_FILE: /run/secrets/postgres_password
      EXECUTIONS_TIMEOUT: 3600
      N8N_LOG_FORMAT: json
    secrets:
      - n8n_encryption_key
      - postgres_password

secrets:
  n8n_encryption_key:
    file: ./secrets/n8n_encryption_key.txt
  postgres_password:
    file: ./secrets/postgres_password.txt

Compose mounts each secret at /run/secrets/<name> inside the container. Add the task runner variables from our task runners guide and, for files and binary data, the storage settings from the binary data guide.

Next steps

Sources

  1. Environment variables overview (n8n docs)
  2. Deployment environment variables (n8n docs)
  3. Endpoints environment variables (n8n docs)
  4. Database environment variables (n8n docs)
  5. Executions environment variables (n8n docs)
  6. Security environment variables (n8n docs)
  7. Logs environment variables (n8n docs)
  8. Configuration methods, the _FILE suffix (n8n docs)
  9. Set a custom encryption key (n8n docs)
  10. n8n 2.0 breaking changes, security defaults (n8n docs)
  11. n8n config package at 2.46.7 (n8n on GitHub)

then8nblog Editors

Editorial team

The then8nblog editorial team researches every article from n8n's release notes, documentation and source code, states the n8n version each guide was tested on, and has every post reviewed by a human editor before it goes live.