n8n Queue Mode: When to Switch and How Many Workers

automation
The n8n, Redis and PostgreSQL logos on a dark technical background, representing an n8n queue mode architecture with a broker and worker processes
Queue mode is three moving parts, not one. That's the whole trade.

Most self-hosted n8n instances never need queue mode. Switch when executions actually start waiting on each other during your busiest hour, when the main process pins CPU, or when you need to deploy without killing in-flight runs — not before. When you do switch, start with two workers (one per 2 vCPUs, minimum two so a restart never empties the pool) at 10–20 concurrency each for I/O-heavy workflows and 2–5 for CPU-heavy ones, then size up from measured queue depth rather than a guess.

We run a self-hosted n8n instance with north of 200 workflows on it for our own operations and for client automation, and we stayed on plain regular mode far longer than most people expect. Queue mode isn't a milestone you graduate to. It's a trade: you get horizontal throughput and zero-downtime deploys, and you pay for it with Redis, a worker fleet, and a Postgres connection pool that will absolutely bite you if you don't do the arithmetic.

Here's how we decide, and the numbers we actually use.

What Queue Mode Actually Changes

In regular mode, one n8n process does everything — serves the editor UI, receives webhooks, and runs your workflows. That's fine, and it's fine for longer than the scaling blog posts suggest.

In queue mode, the main process stops executing workflows. It hands each execution to Redis, and separate worker processes pull jobs off that queue and run them. The workers write results to Postgres, and the main process reads them back for the UI.

| | Regular mode | Queue mode | | --- | --- | --- | | Who runs workflows | The main process | Dedicated worker processes | | Broker | None | Redis 6+ | | Database | SQLite or Postgres | PostgreSQL 13+ (SQLite not viable) | | Scaling | Vertical only — bigger box | Horizontal — add workers | | One slow workflow | Blocks the instance | Blocks one worker slot | | Deploying the main process | Kills in-flight executions | Workers keep draining the queue | | Moving parts that can fail | 1 | 3+ |

That last row is the honest cost. You're trading one failure domain for three. We've had a queue-mode instance go dark not because n8n broke, but because Redis got evicted under memory pressure on a box someone had also decided to run something else on.

When Should You Switch to Queue Mode?

Four signals. If none of them are true, you're solving a problem you don't have.

1. Executions are visibly waiting during your peak hour. Not "we run a lot of workflows" — actually waiting. Open the executions list during your busiest window and look at the gap between when an execution was created and when it started. If that gap is consistently seconds or minutes, you're queueing already, just badly.

2. The main process pins CPU for minutes at a time. A spike is fine. A plateau at 100% across your whole cron burst window means one process can't keep up with the work you're handing it.

3. The editor UI goes sluggish while workflows run. This is the symptom clients notice first, and it's the clearest tell that execution work is starving the process that's also supposed to be serving your interface.

4. You need to deploy or restart without killing in-flight executions. This one is a legitimate reason to switch even if you have plenty of CPU headroom. If your workflows touch billing, client onboarding, or anything where a half-finished run is expensive, the ability to restart the main process while workers keep draining is worth the added complexity on its own.

Here's the one that trips people up: a slow workflow is not a scaling problem. If your complaint is "this workflow takes 40 seconds," queue mode will not help. Queue mode buys throughput, not latency. That same workflow takes 40 seconds on a worker too — you just get to run twenty of them at once. Profile the workflow first. Nine times out of ten it's an unpaginated API call or a Code node looping where a batch endpoint would do.

How Many n8n Workers Do You Need?

Nobody publishes a formula because the honest answer depends on your workflows. Here's the one we start from and then correct with data:

One worker per 2 vCPUs available to the box, with a hard floor of two workers.

The floor matters more than the ratio. With a single worker, any restart, crash or deploy leaves the queue completely unattended, and executions pile up with nothing to drain them. Two is the minimum that survives a worker dying.

| Situation | Workers | Notes | | --- | --- | --- | | Under ~500 executions/day, no bursts | 0 — stay in regular mode | Queue mode is pure overhead here | | A few hundred workflows, moderate cron bursts | 2 | Where most agency instances land | | Heavy cron bursts on the hour, spiky load | 3–4 | Bursts are the real driver, not daily volume | | Sustained high volume + CPU-heavy transforms | 4+ | Verify it isn't one bad workflow first |

Then measure. Watch queue depth through your peak hour: if it climbs during a burst and drains back to zero before the next one, you have enough workers. If it climbs and stays climbing, add one. If it never leaves zero, you probably over-provisioned.

Past four workers, our first assumption is always that something is wrong with a workflow, not that the fleet is undersized. Usually it is.

Budget roughly 200–500MB of RAM per worker depending on how heavy your workflows are, plus about 1GB for Redis and Postgres together. Below 4GB total you're going to have a bad time; 8GB is a sane floor once you're past two workers.

What Concurrency Should Each Worker Run?

Concurrency is how many executions a single worker will run at the same time. It's the setting people leave at the default and then wonder why more workers didn't help.

| Workflow type | Concurrency per worker | Why | | --- | --- | --- | | I/O-heavy — HTTP calls, webhooks, DB queries | 10–20 | The worker spends most of its time waiting, not computing | | CPU-heavy — image work, big transforms, heavy Code nodes | 2–5 | Real compute; more concurrency just thrashes | | Mixed / unknown | Start at 10 | Watch CPU and come down if it pins |

If your workers sit at 100% CPU, lower concurrency and add a worker instead. Raising concurrency on a saturated worker makes everything slower, including the executions that were already running.

If your workers sit near-idle while the queue is deep, concurrency is too low and you're paying for capacity you're not using.

The instinct to crank both numbers at once is what leads directly into the next problem.

The Postgres Connection Pool Trap

This is the failure we see most often after an otherwise clean cutover, and almost nothing warns you about it.

Every concurrent execution needs a database connection. Four workers at 20 concurrency each is up to 80 connections from the fleet, plus whatever the main process holds. Default PostgreSQL max_connections is 100. Add a connection pooler, a backup job and a monitoring query, and you're at the ceiling.

When you hit it, executions don't fail cleanly. They stall — workers block waiting for a connection, the queue backs up, and the UI shows executions sitting in Queued as if you had no workers at all. Every instinct says "add another worker," which makes it worse.

Do the arithmetic before the cutover, not during the incident:

(workers × concurrency) + main process + pooler + your own tooling  <  max_connections

Leave real headroom. If that number is anywhere near your limit, either lower concurrency or raise max_connections and give Postgres the RAM to back it. This one line of arithmetic has saved us more late nights than any dashboard.

Executions Stuck in "Queued" — What It Actually Means

Three causes, in order of how often we see them:

  1. No worker is online. You flipped EXECUTIONS_MODE=queue and never started a worker, or the worker is pointed at a different Redis than the main process. The main process happily accepts executions and posts them to a queue nobody is reading. Check that a worker container is actually running and sharing the same Redis.
  2. The connection pool is exhausted. Covered above. Looks identical from the UI, which is why it's so annoying to diagnose. Check active Postgres connections before you touch worker count.
  3. A burst genuinely outran the fleet. The legitimate case, and the only one where adding a worker is the right move. You'll know it's this because queue depth spikes and then drains, rather than climbing and staying flat.

Worth wiring up alerting for this before you need it — our take on what to monitor is in n8n error handling and monitoring, and the same alerting stack covers stuck executions cleanly.

When We'd Tell You Not To Switch

We've talked clients out of queue mode more than once. Reasons we'd say no:

  • You're still on SQLite. Migrate to Postgres first and run there for a week. Doing both migrations in one window means debugging two systems at once when something goes sideways.
  • Nobody owns the infrastructure. Redis and a worker fleet need someone who will notice when they're unhealthy. If the answer to "who gets paged" is nobody, a bigger single box is genuinely the better engineering decision.
  • You'd be better off on cloud. Queue mode is real ops work. We wrote up the honest version of that trade in self-hosted vs cloud n8n for agencies, and for plenty of teams the managed answer wins.
  • Your problem is one workflow. Fix the workflow.

The official reference for the environment variables and worker commands is the n8n queue mode documentation — it's accurate and worth reading before you change anything. What it can't tell you is whether you should, which is the actual decision.

The Short Version

Regular mode until you have evidence. Postgres before Redis. Two workers minimum. Concurrency matched to whether your workflows wait or compute. Do the connection-pool math before the cutover, not after. Then let queue depth — not a hunch about volume — tell you when to add the third worker.

If you're moving workflows over from another platform first, our Zapier and Make migration notes cover what changes in execution behavior, and if AI agent nodes are in the mix, test them properly before production — agent steps are the ones most likely to hold a worker slot far longer than you budgeted for.

We've been building and running self-hosted n8n at this scale for years, and most of the value is in the boring decisions like these. If your instance is queueing, stalling, or just costing more than it should, get a free automation audit — we'll look at your actual execution data and tell you whether you need workers or a better workflow. You can also see how we approach n8n workflow automation for clients.