Skip to content
MoveWorkflows

n8n queue mode: scaling with workers

Updated 2026-10-21 · 5 min read

Queue mode is how self-hosted n8n scales past one process. The main instance keeps serving the editor, timers and webhooks, but it no longer runs executions itself: it puts them on a Redis queue, and any number of worker processes pick them up. This page explains the architecture, the configuration that every component needs, a working Compose example, and the details that break real deployments (binary data, task runners, large webhook responses).

Start with a single instance (Docker setup). Move to queue mode when executions pile up, the editor slows down during heavy runs, or you need to run more work in parallel than one Node.js process handles.

How it works

From the queue mode docs:

  1. The main instance handles timers and webhook calls and creates an execution, without running it.
  2. It puts the execution ID on Redis.
  3. A free worker takes the job from Redis.
  4. The worker loads the workflow from the database and runs it.
  5. It writes the result to the database and tells Redis the job is done.
  6. Redis notifies the main instance.
Component Runs Needs
Main Editor, API, triggers, test webhooks Postgres, Redis
Worker (n8n worker) Production executions Postgres, Redis, same encryption key
Webhook processor (n8n webhook, optional) Receives production webhook requests Postgres, Redis, EXECUTIONS_MODE=queue
Redis The queue
Postgres Workflows, credentials, executions SQLite isn't supported here

Required configuration

On main, workers and webhook processors:

Variable Value
EXECUTIONS_MODE queue
QUEUE_BULL_REDIS_HOST Redis host (default localhost)
QUEUE_BULL_REDIS_PORT 6379 by default
QUEUE_BULL_REDIS_PASSWORD If Redis has one
N8N_ENCRYPTION_KEY Identical on every process, or workers can't decrypt credentials
DB_TYPE=postgresdb and DB_POSTGRESDB_* Same database everywhere

Optional but common:

Variable Default Purpose
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS false Run manual (editor) executions on workers too
N8N_GRACEFUL_SHUTDOWN_TIMEOUT 30 s Time workers get to finish jobs on shutdown
QUEUE_HEALTH_CHECK_ACTIVE off Enables /healthz and /healthz/readiness on workers
N8N_WEBHOOK_URL – Public webhook base URL (2.30.0+)
N8N_DISABLE_PRODUCTION_MAIN_PROCESS – Main stops handling production webhooks when you use webhook processors

All processes must run the same n8n version.

Compose example

Building on the single-instance file from n8n Docker setup, add Redis and a worker, and set queue variables in a shared block:

x-n8n-env: &n8n-env
  EXECUTIONS_MODE: queue
  QUEUE_BULL_REDIS_HOST: redis
  QUEUE_BULL_REDIS_PORT: "6379"
  DB_TYPE: postgresdb
  DB_POSTGRESDB_HOST: postgres
  DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
  DB_POSTGRESDB_USER: ${POSTGRES_USER}
  DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
  N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
  N8N_RUNNERS_MODE: external
  N8N_RUNNERS_BROKER_LISTEN_ADDRESS: 0.0.0.0
  N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}

services:
  redis:
    image: redis:7
    restart: always

  n8n:
    image: n8nio/n8n:${N8N_VERSION}
    environment:
      <<: *n8n-env
      N8N_WEBHOOK_URL: https://n8n.example.com/
    ports: ["127.0.0.1:5678:5678"]
    depends_on: [postgres, redis]

  main-runners:            # main still runs manual executions
    image: n8nio/runners:${N8N_VERSION}
    environment:
      N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
      N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
    depends_on: [n8n]

  n8n-worker:
    image: n8nio/n8n:${N8N_VERSION}
    command: worker --concurrency=10
    environment:
      <<: *n8n-env
    depends_on: [n8n]

  worker-runners:
    image: n8nio/runners:${N8N_VERSION}
    environment:
      N8N_RUNNERS_TASK_BROKER_URI: http://n8n-worker:5679
      N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
    depends_on: [n8n-worker]

Postgres and its volume are as in the single-instance file. Scale workers with additional worker services (each with its own runners sidecar).

Task runners in queue mode

The task runner docs are explicit: each worker needs its own runners sidecar. If OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is false (the default), the main instance still runs manual executions and needs its own sidecar too. A worker without runners fails every Code node, which is the most common first-day queue mode problem. Custom npm or Python packages must be in every runners image.

Worker concurrency

A worker runs 10 executions in parallel by default; change it with n8n worker --concurrency=N. n8n recommends 5 or higher: many workers with low concurrency each hold database connections and can exhaust the pool. Our rule of thumb, not n8n's: add workers once one worker at concurrency 10 to 20 is consistently busy.

Webhook processors

For high webhook volume, run separate n8n webhook processes behind a load balancer:

  • Route /webhook/* and /webhook-waiting/* to the webhook processors.
  • Route everything else, including /webhook-test/* (editor test runs), to main.
  • Don't put main in the webhook pool; it degrades the editor. Optionally set N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true.

Pitfalls

Problem Cause Fix
Binary data missing between steps Filesystem binary storage isn't supported in queue mode N8N_DEFAULT_BINARY_DATA_MODE=database, or S3 external storage (Business/Enterprise)
Credentials fail on workers Different encryption key Same N8N_ENCRYPTION_KEY everywhere
Code nodes fail on workers No runners sidecar on the worker One sidecar per worker
"The response is too large to be sent back from the worker" Respond to Webhook body over N8N_WEBHOOK_RESPONSE_RELAY_SIZE_MAX (64 MiB) Raise it, or offload to storage (2.34.0+)
Webhooks slower than before Request now hops main → Redis → worker Expected overhead; add webhook processors for volume

Multi-main (Enterprise)

Queue mode can run several main processes for high availability: one leader runs at-most-once work (timers, pollers, pruning), followers serve the UI and API. It needs N8N_MULTI_MAIN_SETUP_ENABLED=true on every main, Postgres, Redis, the same version everywhere, and a load balancer with sticky sessions. It's a self-hosted Enterprise feature and isn't available on n8n Cloud.

Do you need it after leaving Pipedream?

Pipedream ran and scaled the infrastructure for you, and you paid per credit. On self-hosted n8n, one instance is enough for most migrated projects of a few dozen workflows. Queue mode becomes relevant with many high-frequency webhooks, long-running Code nodes, or heavy schedules that overlap.

Before sizing, look at what you're moving: our converter report shows trigger types and code steps per workflow, and the code step checker shows what a single step needs. The report and 1 workflow are free. Full export: $3 per workflow, $19 minimum — coming soon. Then follow migrate Pipedream to n8n.

Not affiliated with Pipedream or n8n.

FAQ

What is queue mode in n8n?
A self-hosted setup where the main instance receives triggers and webhooks, puts execution IDs on a Redis queue, and separate worker processes run the executions. You scale by adding workers.
Which environment variables enable n8n queue mode?
EXECUTIONS_MODE=queue on the main instance and every worker, QUEUE_BULL_REDIS_HOST and QUEUE_BULL_REDIS_PORT (plus password if set), the same N8N_ENCRYPTION_KEY everywhere, and a shared Postgres database.
Can I use SQLite with queue mode?
No. n8n doesn't support running a distributed setup over SQLite; use Postgres.
How many executions does an n8n worker run at once?
10 by default. Change it with n8n worker --concurrency=N. n8n recommends 5 or higher; many workers with low concurrency can exhaust the database connection pool.
Is queue mode available on n8n Cloud?
On self-hosted n8n you configure it yourself. n8n's pricing page lists queue mode as included on Cloud Enterprise. Multi-main is self-hosted Enterprise; the docs say it isn't available on n8n Cloud.

Related

Sources