n8nio/n8n: the web process serves the editor, the REST API and your workflows’ webhooks, and a Sevalla PostgreSQL database keeps workflows, credentials, executions and files, so the application needs no disk. In queue mode, the web process puts each execution on a Valkey queue and background workers run them, so long or busy workflows don’t slow down the editor or the webhooks.
At a glance
Environment variables
Before you begin
- A Sevalla company with a payment method: n8n needs the S1 size or larger.
- OpenSSL on your computer, to generate the encryption key (
openssl versionprints its version).
Create the database
Open the create form
Choose PostgreSQL
Name and place it
n8n-db, choose the Data center where n8n will run, and choose the Size. This guide was tested on DB1.Create it
Create the application
Choose the image
n8nio/n8n:2.45.6 in Docker image. Keep the Registry credential at None (public image).Name, place and size it
n8n, choose the database’s Data center, and choose the Size S1.Create it without deploying
n8n-x7k2m.sevalla.app: N8N_WEBHOOK_URL needs it.n8nio/n8n is the image n8n publishes on Docker Hub; n8n’s own examples also use docker.n8n.io/n8nio/n8n, which serves the same image. The tag pins one n8n release: 2.45.6 is the current stable release. Moving tags such as latest and stable change under you on the next deployment, and an n8n upgrade migrates the database, so pin a version and upgrade on purpose.
Connect the database
n8n reads its database settings from five separate variables, not a connection URL. The internal connection adds the same values under other names; rename them as you add them.Open the database's networking
n8n-db. Click the Networking tab.Add the connection
n8n Application.Rename the variables
DB_HOST to DB_POSTGRESDB_HOST, DB_PORT to DB_POSTGRESDB_PORT, DB_DATABASE to DB_POSTGRESDB_DATABASE, DB_USERNAME to DB_POSTGRESDB_USER and DB_PASSWORD to DB_POSTGRESDB_PASSWORD. Click the trash icon next to DB_URL: n8n doesn’t read it.Save
Set the environment variables
Generate the encryption key on your computer, and store it in your password manager before you add it:N8N_HOST or N8N_PROTOCOL: n8n uses them only to build the URL when N8N_WEBHOOK_URL is empty. Keep N8N_PROTOCOL at its default http: Cloudflare and Sevalla handle HTTPS, and n8n serves plain HTTP on 8080.
Add a readiness probe
n8n takes about 10 seconds to start, and runs its database migrations first. A readiness probe keeps sending requests to the running version until the new one is ready.Open the web process
Turn on the probe
/healthz/readiness. Keep the Port at 8080.Save
503 for about 8 seconds while the new instance started. The probe also protects you from a broken start: a deployment whose instance never becomes ready fails after 20 minutes with ❌ Failed to deploy Web. in its build log, and the previous version keeps running. See Keep the encryption key for one cause.
Deploy n8n
Click the Overview tab, click Deploy now, then click Deploy. The deployment pulls the image and starts the web process; there’s no build.Open n8n
Create the owner account
Verify the deployment
-
On the Deployments tab, the deployment’s status is Deployed. With the API, Get deployment (
getDeploymentV3) returns"status": "success". -
The application’s runtime logs show
Version: 2.45.6, then these two lines once n8n is ready. Search them forEditor is now accessible via:, or call Get application runtime logs (getApplicationRuntimeLogsV3) withsearch=Editor.Runtime logs -
The readiness endpoint answers:
Run a workflow from a webhook
This workflow answers aPOST to /webhook/orders with a message built by a Code node.
Create a workflow
Paste the workflow
Publish it
https://n8n-x7k2m.sevalla.app/webhook/orders, built from N8N_WEBHOOK_URL. Call it:
404 with The requested webhook "POST orders" is not registered.
Keep the encryption key
N8N_ENCRYPTION_KEY must stay the same for the life of the instance. n8n 2.45 stores keys derived from it in the database, and checks them at every start.
With the readiness probe, a deployment with the wrong key fails after 20 minutes and the running version keeps serving. Either way, set the variable back to the original key and deploy again: the credentials and workflows are intact.
What needs a disk
Nothing, once PostgreSQL,N8N_ENCRYPTION_KEY and N8N_DEFAULT_BINARY_DATA_MODE=database are set. n8n’s folder in the image, /home/node/.n8n, holds only what those settings replace or what n8n can rebuild:
Scale with queue mode
In queue mode, the web process keeps the editor, the API and the webhooks, and puts each execution in a queue in Valkey; background workers take executions from the queue and run them. Add workers when executions slow down the editor or wait for each other.Create and connect Valkey
Create the database
n8n-queue, choose the same Data center, and click Create database. Wait for Ready.Connect n8n
n8n-queue’s Networking tab, click Add internal connection and choose the n8n Application. Turn on Add environment variables to the application, change the keys REDIS_HOST to QUEUE_BULL_REDIS_HOST, REDIS_PORT to QUEUE_BULL_REDIS_PORT and REDIS_PASSWORD to QUEUE_BULL_REDIS_PASSWORD, delete REDIS_URL, and click Add internal connection.Add the queue variables
n8n application’s Environment variables tab, add these variables:OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS sends the runs you start in the editor to the workers too; without it, n8n logs a deprecation warning in queue mode. N8N_WORKER_SUSPEND_EXECUTIONS_ON_SHUTDOWN keeps executions alive across deployments: see Running executions during a deployment.
Add a worker
Create the process
Set the command and size
Worker and the Custom start command exec n8n worker --concurrency=10, and pick the Resource S1.Create and deploy
SIGTERM on, so exec replaces the shell with n8n, which then receives SIGTERM and shuts down cleanly. --concurrency=10 is how many executions one worker runs at a time; with N8N_CONCURRENCY_PRODUCTION_LIMIT set, that variable wins. To run more executions in parallel, raise the worker’s Instance count: each instance takes executions from the same queue.
Keep the web process at 1 instance. Several main instances at once are n8n’s multi-main setup, which needs an n8n license that includes it; without one, n8n refuses to start in that mode.
Verify queue mode
-
Search the runtime logs for
n8n worker is now ready. The worker logs:Runtime logs -
Call the webhook workflow again. It answers the same way, and the runtime logs show the web process handing the execution to the worker:
Runtime logs
Running executions during a deployment
Each deployment replaces the worker’s instance. Sevalla sendsSIGTERM 5 seconds after the shutdown begins and stops the instance 30 seconds after it began. n8n pauses the queue, waits for running executions, and exits after N8N_GRACEFUL_SHUTDOWN_TIMEOUT.
Build an AI agent workflow
An AI Agent node can answer requests that reach a webhook, with a chat model and tools. A public webhook that calls a model spends money for anyone who finds it, so this one requires a token in theAuthorization header.
Add the Anthropic credential
N8N_ENCRYPTION_KEY and stores it in PostgreSQL; the key isn’t in any workflow or environment variable.Paste the workflow
Choose the credentials
Authorization and the Value Bearer followed by a long random token, for example from openssl rand -hex 24. Open the Anthropic Chat Model node and choose your Anthropic credential.Publish it
claude-haiku-5-5 is Anthropic’s fastest and cheapest current model; change the model in the Anthropic Chat Model node. Call the webhook with your token:
403 with Authorization data is wrong!.
Keep "settings": { "executionOrder": "v1" } when you create workflows through n8n’s API: without it, n8n runs the workflow in its legacy execution order, the agent gets an empty result from every tool, and the webhook answers {"code":0,"message":"No item to return was found"}. Workflows you create in the editor use v1.
Content an agent reads, such as a customer’s message, can contain instructions meant to mislead it. Give an agent read-only tools, and let the workflow’s own nodes, after a check, take actions you can’t undo, such as refunds or emails. Set a spending limit in your model provider’s console.
To use models from other providers in the AI Agent node, see OpenRouter in n8n.
Upgrade n8n
n8n migrates its database when a new version starts, and the migration can’t be undone by starting the old image again.- Read the release notes of every version between yours and the new one on n8n’s GitHub releases.
- Back up
n8n-db: on its Backups tab, create a manual backup. See Backups. - On the application’s Settings tab, in the Source section, click Update source, change the tag in Docker image (for example to
n8nio/n8n:2.46.2once it’s stable), and click Update source. - Deploy. The web process runs the migrations at start; workers use the same image, so they move to the new version with the same deployment.
Add a custom domain
To serve n8n from your own domain, such asautomation.example.com, add it on the application’s Domains tab and create the DNS records Sevalla shows; the web process must be larger than H1, which S1 is. Then change N8N_WEBHOOK_URL to https://automation.example.com/ and deploy. Webhook URLs you’ve given to other services change with it. See Custom domains.
Troubleshoot
Deploy with the API
These calls create the same deployment without the dashboard: the database, the application, the variables, the readiness probe, and the first deployment, then queue mode. They need:- An API key that can create applications and databases, in
SEVALLA_API_KEY. curl,jqandopenssl.
Choose the location
listClustersV3) returns the locations your company can use. Pick one by its region ID, here Frankfurt:sevalla resources clusters. MCP: get_platform_options.Look up the sizes
listProcessResourceTypesV3) and List database resource types (listDatabaseResourceTypesV3) return the size IDs:sevalla resources process-types and sevalla resources db-types. MCP: get_platform_options.Create the database
createDatabaseV3). The API doesn’t return the password later, so generate it here and keep it in a variable:sevalla databases create --name n8n-db --type postgresql --db-version 18 --cluster $CLUSTER_ID --resource-type $DB1 --db-name n8n --db-user n8n --db-password $DB_PASSWORD. MCP: sevalla_api_create with createDatabaseV3 and the same body (create_database generates a password it doesn’t return, and n8n needs it).Wait for the database
getDatabaseV3) until status is ready, then read the internal hostname:sevalla databases get $DB_ID. MCP: get_database.Create the application
createApplicationV3) with the Docker image source. It doesn’t start a deployment:sevalla apps create --name n8n --cluster $CLUSTER_ID --source dockerImage --docker-image n8nio/n8n:2.45.6. MCP: create_application with deploy: false.Read the domain and the web process
listApplicationDomainsV3) and List processes (listProcessesV3):sevalla apps domains list --app-id $APP_ID and sevalla apps processes list --app-id $APP_ID. MCP: get_application.Size the web process and add the readiness probe
updateProcessV3). The API creates the web process at S1 already; send the size anyway if you change it. Always send timeoutSeconds: without it, the probe gets 120 seconds instead of the dashboard’s 1:sevalla apps processes update $WEB_ID --app-id $APP_ID --resource-type $S1 (the CLI can’t set a probe). MCP: sevalla_api_update with updateProcessV3 and the same body.Connect the database
createApplicationInternalConnectionV3). Unlike the dashboard, it adds no variables:sevalla apps internal-connections create $APP_ID --target-id $DB_ID --target-type database. MCP: sevalla_api_create with createApplicationInternalConnectionV3.Add the environment variables
createEnvironmentVariableV3), once per variable. Store N8N_ENCRYPTION_KEY somewhere safe before you send it:sevalla apps env-vars create $APP_ID --key DB_TYPE --value postgresdb, once per variable; the CLI makes each variable available during runtime and build, which makes no difference for an image. MCP: set_environment_variables with all of them in variables.Deploy
triggerDeploymentV3):sevalla apps deployments trigger $APP_ID. MCP: trigger_deployment.Wait for the deployment
getDeploymentV3) until status is final (success, failed, cancelled or skipped), for up to 30 minutes; Get application deployment logs (getApplicationDeploymentLogsV3) shows why one failed:sevalla apps deployments get $DEPLOYMENT_ID --app-id $APP_ID and sevalla apps deployments logs $DEPLOYMENT_ID --app-id $APP_ID. MCP: get_deployment and get_deployment_logs.Check n8n
getApplicationRuntimeLogsV3) shows the URL n8n uses:sevalla apps logs runtime $APP_ID --search $APP_HOST. MCP: search_runtime_logs.https://$APP_HOST in a browser and create the owner account at once: n8n has no API for the first account.
Add queue mode with the API
Create Valkey
createDatabaseV3), then wait for ready as before:sevalla databases create --name n8n-queue --type valkey --db-version 9.0 --cluster $CLUSTER_ID --resource-type $DB1 --db-name n8n-queue --db-password $QUEUE_PASSWORD. MCP: sevalla_api_create with createDatabaseV3.Connect it
createApplicationInternalConnectionV3):sevalla apps internal-connections create $APP_ID --target-id $QUEUE_ID --target-type database. MCP: sevalla_api_create with createApplicationInternalConnectionV3.Add the queue variables
createEnvironmentVariableV3), with the add_var function from before:sevalla apps env-vars create, once per variable. MCP: set_environment_variables.Create the worker
createProcessV3). Every process needs scaling_strategy and resource_type_id:sevalla apps processes create $APP_ID --name Worker --type worker --resource-type $S1 --command "exec n8n worker --concurrency=10". MCP: sevalla_api_create with createProcessV3 and the same body.Deploy and check the worker
sevalla apps logs runtime $APP_ID --search "worker is now ready". MCP: search_runtime_logs.