n8n queue mode: Scaling with Redis and workers

Learn how to run n8n in queue mode with Redis and workers. A step-by-step guide for stable scaling on your VPS.

Why queue mode matters

When you first install n8n it runs in single node mode. The editor and the execution engine share the same process. That’s fine for small flows, but once you start running heavy automations or high volumes of webhooks, the editor will feel sluggish.

Queue mode separates concerns. The editor stays responsive, jobs are pushed into Redis, and one or more workers pull them for execution. This model is how you scale n8n without losing stability.

How queue mode works under the hood

At the heart of queue mode are three moving parts:

  • Editor process: Handles the UI, API, and scheduling. It writes jobs to Redis.
  • Redis: Stores jobs temporarily. Think of it as the queue where workflows wait their turn.
  • Workers: One or more worker processes pull jobs from Redis and run them. Each worker connects to the same PostgreSQL database.

The database remains the source of truth. Workflow definitions, credentials, and execution logs are all stored there. Redis only holds job metadata while jobs are waiting or running.

VPS requirements for queue mode

Queue mode needs more resources than single node, because you’re running at least three containers instead of two. At minimum:

  • 2 vCPU / 4 GB RAM with NVMe storage for testing
  • 4 vCPU / 8 GB RAM for real production with a few workers
  • 8+ vCPU / 16+ GB RAM for higher concurrency or heavy tasks

Keep PostgreSQL on NVMe. Place the VPS near your APIs to reduce webhook latency.

Setting up queue mode with Docker Compose

Here’s a simple setup you can copy into your docker-compose.yml:

version: "3.9"
services:
  editor:
    image: n8nio/n8n:latest
    restart: unless-stopped
    env_file: .env
    command: n8n
    depends_on:
      - postgres
      - redis
    ports:
      - "5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n

  worker:
    image: n8nio/n8n:latest
    restart: unless-stopped
    env_file: .env
    command: n8n worker
    depends_on:
      - postgres
      - redis
    volumes:
      - n8n_data:/home/node/.n8n

  redis:
    image: redis:7-alpine
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: n8n
    volumes:
      - pg_data:/var/lib/postgresql/data

volumes:
  n8n_data:
  pg_data:

In your .env file add:

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_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=<your_password>

Then bring it up:

docker compose up -d

Scale workers easily:

docker compose up -d --scale worker=3

Now three workers will process jobs in parallel.

Binary data and queue mode

This is where many tutorials get it wrong. By default n8n stores binary data in memory and keeps references in the database. That’s safe in queue mode. Do not try to share a filesystem mount for binary data between editor and workers — it’s not supported and leads to corruption. If you need persistent binaries, use an external storage adapter like S3 or MinIO.

Reverse proxy and public URLs

Queue mode still needs a reverse proxy. Make sure your proxy forwards these headers:

  • X-Forwarded-Proto
  • X-Forwarded-Host
  • X-Forwarded-For

In .env set:

N8N_HOST=automation.example.com
N8N_PROTOCOL=https
WEBHOOK_URL=https://automation.example.com/
N8N_PROXY_HOPS=1

This ensures webhook URLs resolve correctly in the editor.

Monitoring queue mode

You need to keep an eye on:

  • Queue depth: number of jobs waiting in Redis
  • Execution time: how long workflows take to finish
  • Worker health: are workers connected and pulling jobs
  • Database load: Postgres connections and disk usage
  • Redis latency: command timeouts or blocked clients

Prometheus and Grafana are common choices. For a quick check, Redis has redis-cli monitor and n8n exposes metrics you can scrape.

When to scale workers

Add workers when:

  • Queue depth keeps growing over time
  • Execution times increase under load
  • Webhooks start backing up
  • CPU is consistently maxed out during jobs

Small, multiple workers are usually more effective than one big worker. They let you parallelize across CPUs and handle more bursts.

Common pitfalls in queue mode

  • Credentials disappear: encryption key changed. Generate it once and keep it safe.
  • Jobs hang forever: Redis not reachable or not enough workers.
  • Webhook URLs wrong: proxy headers missing or WEBHOOK_URL not set.
  • Database bloat: old execution logs piling up. Use pruning settings.

Best practices for running queue mode in production

  • Keep Postgres on its own volume and back it up nightly.
  • Run Redis with persistence disabled unless you need durability.
  • Use health checks to auto-restart stuck workers.
  • Test restores and snapshots before major upgrades.
  • Monitor early, not after users complain.

Closing thoughts

Queue mode is how you take n8n from a personal toy to a production automation system. It separates the editor from the heavy lifting, lets you scale horizontally, and keeps things stable under load. With Redis, Postgres, a couple of workers, and a clean VPS setup, you can run automations that would choke a single-node install.