# How to Enable Queue Mode in n8n

- Tool: n8n
- Difficulty: Intermediate
- Time required: 30-40 minutes
- Compatibility: n8n 1.0+, PostgreSQL 12+, Redis 6+
- Last updated: March 2026

## TL;DR

Enable queue mode in n8n to scale workflow execution across multiple worker processes. Set EXECUTIONS_MODE=queue, configure Redis as the message broker, use PostgreSQL as the database, and start separate main and worker instances. Queue mode prevents the main instance from being blocked by long-running workflows and lets you scale workers independently.

## What Queue Mode Does and When to Use It

By default, n8n runs in 'regular' mode where the main process handles both the UI/API and workflow execution. This works for low-volume setups, but becomes a bottleneck when running many workflows or workflows with long-running nodes. Queue mode separates these concerns: the main instance handles the UI, API, webhooks, and scheduling, while worker instances pull and execute workflows from a Redis-backed queue. This architecture lets you scale workers independently, prevents the UI from becoming unresponsive during heavy execution, and enables horizontal scaling.

## Before you start

- A running n8n instance with PostgreSQL as the database (SQLite is not supported for queue mode)
- Redis 6+ server accessible from both main and worker instances
- Docker or npm installation of n8n
- Basic understanding of n8n environment variables

## Step-by-step guide

### 1. Ensure PostgreSQL is configured as n8n's database

Queue mode requires PostgreSQL — it does not work with SQLite. If you are still using SQLite, migrate to PostgreSQL first. Verify that your DB_TYPE is set to postgresdb and the DB_POSTGRESDB_* variables point to a working PostgreSQL instance. Both the main instance and all workers must connect to the same PostgreSQL database.

```
# Verify these environment variables are set
echo $DB_TYPE          # Should be: postgresdb
echo $DB_POSTGRESDB_HOST
echo $DB_POSTGRESDB_DATABASE
```

**Expected result:** DB_TYPE is postgresdb and n8n connects to PostgreSQL successfully.

### 2. Set up Redis for the execution queue

Install and start Redis. The simplest approach is Docker. Redis acts as the message broker between the main instance and workers. When a workflow needs to execute, the main instance pushes a job to Redis, and the first available worker picks it up. Use a dedicated Redis instance for n8n to avoid interference with other applications.

```
# Run Redis with Docker
docker run -d --name n8n-redis \
  -p 6379:6379 \
  redis:7-alpine

# Verify Redis is running
docker exec n8n-redis redis-cli ping
# Expected output: PONG
```

**Expected result:** Redis is running and responds to PING with PONG.

### 3. Configure environment variables for queue mode

Set the required environment variables on both the main instance and all workers. EXECUTIONS_MODE=queue enables queue mode. QUEUE_BULL_REDIS_HOST and QUEUE_BULL_REDIS_PORT point to your Redis instance. All instances must share the same N8N_ENCRYPTION_KEY and database configuration. The main instance and workers use the same environment variables — they differ only in how they are started.

```
# Queue mode configuration (set on ALL instances)
export EXECUTIONS_MODE=queue
export QUEUE_BULL_REDIS_HOST=localhost
export QUEUE_BULL_REDIS_PORT=6379
# export QUEUE_BULL_REDIS_PASSWORD=your_redis_password  # if auth is enabled

# Database (must be PostgreSQL)
export DB_TYPE=postgresdb
export DB_POSTGRESDB_HOST=localhost
export DB_POSTGRESDB_PORT=5432
export DB_POSTGRESDB_DATABASE=n8n_db
export DB_POSTGRESDB_USER=n8n_user
export DB_POSTGRESDB_PASSWORD=your_secure_password

# Shared encryption key (MUST be identical on all instances)
export N8N_ENCRYPTION_KEY=your_encryption_key_here

# Webhook URL (main instance URL)
export WEBHOOK_URL=https://n8n.yourdomain.com
```

**Expected result:** All environment variables are set and consistent across main and worker instances.

### 4. Start the main instance

Start n8n normally. In queue mode, the main instance handles the editor UI, REST API, webhooks, and scheduling. It pushes execution jobs to Redis but does not execute workflows itself (unless a worker is not available). The main instance must be started before workers.

```
# Start the main instance
n8n start

# Or with Docker
docker run -d --name n8n-main \
  -p 5678:5678 \
  -e EXECUTIONS_MODE=queue \
  -e QUEUE_BULL_REDIS_HOST=n8n-redis \
  -e QUEUE_BULL_REDIS_PORT=6379 \
  -e DB_TYPE=postgresdb \
  -e DB_POSTGRESDB_HOST=postgres \
  -e DB_POSTGRESDB_DATABASE=n8n_db \
  -e DB_POSTGRESDB_USER=n8n_user \
  -e DB_POSTGRESDB_PASSWORD=your_secure_password \
  -e N8N_ENCRYPTION_KEY=your_encryption_key_here \
  -e WEBHOOK_URL=https://n8n.yourdomain.com \
  docker.n8n.io/n8nio/n8n
```

**Expected result:** The main instance starts, connects to PostgreSQL and Redis, and serves the editor at port 5678.

### 5. Start one or more worker instances

Start worker instances using the n8n worker command. Workers connect to the same PostgreSQL database and Redis instance. Each worker pulls jobs from the queue and executes them. Start as many workers as your server can handle. Each worker can execute one workflow at a time by default (configurable with N8N_CONCURRENCY_PRODUCTION_LIMIT).

```
# Start a worker (npm installation)
n8n worker

# Start a worker with concurrency limit
N8N_CONCURRENCY_PRODUCTION_LIMIT=5 n8n worker

# Or with Docker
docker run -d --name n8n-worker-1 \
  -e EXECUTIONS_MODE=queue \
  -e QUEUE_BULL_REDIS_HOST=n8n-redis \
  -e QUEUE_BULL_REDIS_PORT=6379 \
  -e DB_TYPE=postgresdb \
  -e DB_POSTGRESDB_HOST=postgres \
  -e DB_POSTGRESDB_DATABASE=n8n_db \
  -e DB_POSTGRESDB_USER=n8n_user \
  -e DB_POSTGRESDB_PASSWORD=your_secure_password \
  -e N8N_ENCRYPTION_KEY=your_encryption_key_here \
  -e N8N_CONCURRENCY_PRODUCTION_LIMIT=5 \
  docker.n8n.io/n8nio/n8n worker
```

**Expected result:** The worker connects to Redis and PostgreSQL, then waits for jobs. The console shows 'Worker is ready to process executions'.

### 6. Verify queue mode is working

Open the n8n editor and trigger a workflow manually or via webhook. Check the execution history to verify the execution was processed by a worker. The execution details show which instance processed the job. Also verify that the UI remains responsive during execution — this confirms the main instance is offloading work to workers.

**Expected result:** Workflow executions are processed by workers and the main instance UI remains responsive during heavy workloads.

## Complete code example

File: `docker-compose-queue-mode.yml`

```yaml
version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    restart: always
    environment:
      POSTGRES_DB: n8n_db
      POSTGRES_USER: n8n_user
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U n8n_user -d n8n_db']
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: always
    volumes:
      - redis_data:/data
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 5s
      timeout: 5s
      retries: 5

  n8n-main:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    ports:
      - '5678:5678'
    environment:
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n_db
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - WEBHOOK_URL=${WEBHOOK_URL}
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  n8n-worker:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    command: worker
    deploy:
      replicas: 2
    environment:
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n_db
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_CONCURRENCY_PRODUCTION_LIMIT=5
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

volumes:
  postgres_data:
  redis_data:
  n8n_data:
```

## Common mistakes

- **Trying to use queue mode with SQLite** — undefined Fix: Queue mode requires PostgreSQL. Migrate to PostgreSQL by setting DB_TYPE=postgresdb and the DB_POSTGRESDB_* variables.
- **Using different N8N_ENCRYPTION_KEY values on main and worker instances** — undefined Fix: All instances must share the exact same encryption key. Generate one with openssl rand -hex 32 and use it everywhere.
- **Starting workers before the main instance on first setup** — undefined Fix: Start the main instance first so it creates the database schema. Workers can be started afterward.
- **Not setting WEBHOOK_URL on the main instance, causing incorrect webhook URLs** — undefined Fix: Set WEBHOOK_URL to your public URL so n8n generates correct webhook paths. Workers do not need this variable.

## Best practices

- Always use PostgreSQL with queue mode — SQLite does not support concurrent access from multiple processes
- Use the same N8N_ENCRYPTION_KEY on all instances — mismatched keys cause credential decryption failures
- Start with 2-3 workers and scale based on queue depth monitoring
- Set N8N_CONCURRENCY_PRODUCTION_LIMIT to 3-5 per worker to allow parallel execution within each worker
- Use Redis persistence (AOF or RDB snapshots) so pending jobs survive a Redis restart
- Monitor Redis memory usage — large workflow payloads in the queue can consume significant memory
- Set EXECUTIONS_DATA_PRUNE=true and EXECUTIONS_DATA_MAX_AGE=168 to auto-prune old execution data
- Use Docker Compose replicas to scale workers easily: deploy.replicas: N

## Frequently asked questions

### Does queue mode require a paid n8n license?

No. Queue mode is available in the open-source community edition of n8n. It is a configuration option, not a paid feature.

### Can I run the main instance and workers on the same server?

Yes. For moderate workloads, running everything on one server is fine. For high-volume production, run workers on separate servers for better resource isolation.

### How many workers should I run?

Start with 2-3 workers with N8N_CONCURRENCY_PRODUCTION_LIMIT=5 each. Monitor queue depth via Redis or n8n metrics. Add more workers if jobs wait longer than acceptable.

### What happens if a worker crashes during execution?

The job remains in Redis. When the worker reconnects or another worker picks it up, the execution is retried based on n8n's retry settings. Data is not lost because execution state is in PostgreSQL.

### Can I use Redis Cluster or Redis Sentinel with n8n queue mode?

n8n uses Bull queue library, which supports Redis Sentinel for high availability. Set the QUEUE_BULL_REDIS_* variables to point to your Sentinel setup. Redis Cluster is not supported by Bull.

### Can RapidDev help me scale n8n with queue mode for production?

Yes. RapidDev can architect and deploy a production n8n setup with queue mode, including Redis configuration, worker scaling, monitoring with Prometheus/Grafana, and high-availability patterns.

---

Source: https://www.rapidevelopers.com/n8n-tutorial/how-to-enable-queue-mode-in-n8n
© RapidDev — https://www.rapidevelopers.com/n8n-tutorial/how-to-enable-queue-mode-in-n8n
