Execution designEvidence checked 2026-11-06

n8n queue mode, workers and concurrency: what each layer actually scales

A concurrency cap controls admission. Redis queue mode distributes production executions across worker processes. A Code task runner isolates Code-node execution. Choose only after you know which execution class is pressing a limit and can operate the shared dependencies the change introduces.

One workflow, several execution paths — map the path before changing capacity.
Conditional decision. If production bursts need admission control in one deployment, start by evaluating the regular-mode production limit. If executions need to be distributed, queue mode adds Redis, shared supported database connectivity and key distribution. If Code-node isolation is the problem, assess task runners separately. If you cannot identify the affected execution class or recover the shared state, pause the change and collect the worksheet evidence first.

Conditional verdict: identify the bottleneck before adding a worker

Record the selected image tag, edition and matching release notes before changing topology. Never use mutable latest as a version decision. The captured n8n 3.0 sources conflict: the breaking-change page calls it early access while release notes carry a potentially different channel label. Resolve the selected tag against release notes, migration report and pre-publication check; do not invent a minor version.

Observed needCandidate mechanismDependency addedDoes not solveNext check
Production bursts stall one instanceRegular production capQueued work and logsExcluded classes; Code isolationArrival rate, wait age, startup behavior
Distribute production executionRedis queue modeRedis, shared DB, same keyHA, backup, throughput guaranteeDB, network, binary path, limits
Isolate Code nodesExternal task runnerMatching version and placementGeneral workflow distributionRelease guide and security boundary
Assistant-generated codeOptional Assistant sandboxPrivileged Docker-in-Docker trustQueue worker, model or Code runnerEdition and threat boundary

Four concepts people incorrectly call “queue” or “runner”

Regular-mode production concurrency

Regular mode has no production concurrency limit by default. The documented N8N_CONCURRENCY_PRODUCTION_LIMIT=20 is an example, not a default or recommendation. When set, trigger/webhook production executions are admitted up to the limit and excess work waits FIFO. This limits admission, not execution capacity.

Manual, sub-workflow, error and CLI executions are outside this cap. Queued work cannot be retried; cancelling/deleting removes it. On startup, n8n resumes up to the limit and re-enqueues the rest. Confirm release behavior with owners.

Execution paths

Production trigger → configured limit → execute or FIFO wait. Manual UI, sub-workflow, error and CLI executions bypass this cap; evaluation has a separate limit.

Redis queue-mode workers

Set EXECUTIONS_MODE=queue on main and workers. Main puts execution IDs in Redis; workers read workflow state from the shared database, execute and report through Redis. The caller stays connected to main or the webhook process, so this handoff can add latency.

Workers need the supported shared DB, Redis and main's same instance key. Processes on one VPS share limits and failure domain; another host adds network, recovery and billing work, not HA.

Queue dataflow

Caller → main/webhook → Redis execution ID → worker ↔ shared database. All required processes need the same instance key; a Code runner sidecar is separate.

External Code-node task runners

Task runners broker Code-node tasks between n8n and a runner process. They are a security and execution boundary for Code tasks; they do not pick general workflow jobs from Redis. Internal runner mode executes under the same user and host boundary as n8n, so a sandbox escape can reach that user's resources. Use the selected release's external-runner design and security guidance when Code isolation is a requirement.

The runner must match the n8n version. The captured runner guide says each queue worker needs its own sidecar. The older documented exception for manual executions on main when manual work is not offloaded must not be carried forward without checking the selected release: n8n 3 changes manual execution behavior on workers. Confirm where manual Code tasks run and which sidecars they require before counting services. Code timeout and memory policy belong in workload acceptance; Article 7 handles AI execution contexts and Article 9 handles runner secrets and hardening.

Assistant sandbox and multi-main are different again

The optional Assistant Docker-in-Docker sandbox supports generated code. It is privileged/root-equivalent, not a workflow worker, Code runner or resident model; do not count it as queue capacity.

Multi-main is also distinct from adding workers. The captured queue guide requires matching n8n versions, shared Postgres and Redis, opt-in configuration and session persistence for multi-main. It is an Enterprise capability. Queue mode is documented as Community; viewing workers in the n8n UI is Enterprise. The optional worker health endpoints are a separate operational probe. Recheck edition and license terms for the selected release before relying on any boundary below.

CapabilityCaptured boundaryVerify before designCost hand-off
Redis queue modeQueue mode listed in CommunitySelected tag, supported DB and exact editionPrice Redis and DB placement once in Article 2
Multi-mainEnterprise; shared Postgres/Redis, matching version, opt-in and session persistenceLicense and all topology prerequisitesRecord license and selected services; do not infer price
UI worker viewEnterprise in captured docsCurrent selected edition feature accessUnverified cash value remains unresolved
Assistant sandboxOptional privileged Docker-in-Docker boundaryWhether Assistant feature and sandbox are actually selectedCount only selected host/service and measured terms

Concurrency precedence and workload classes

Do not add concurrency controls together. In queue mode, non--1 N8N_CONCURRENCY_PRODUCTION_LIMIT takes precedence; otherwise --concurrency applies, falling back to its default. Record the effective value per process. Worker flag default is 10; the guide recommends at least 5. Neither means jobs per host. Low per-worker concurrency across many workers can exhaust DB connections.

Fill this inventory with observed classes and selected-release behavior. Do not infer manual, evaluation or waiting behavior from production triggers.

Source / classRegular production cap?Queue worker path?Profile and retry question to recordOwner
Production trigger or webhookYesYes in queue modePayload, duration, wait; verify failure/retryWorkflow owner
Manual UI runNoRelease-dependent; verify n8n 3UI data copies; runner placementOperator + author
Sub-workflowNoVerify caller/version behaviorNested volume, return payload, cancellationWorkflow owner
Error workflowNoVerify release and trigger pathFailure burst, recursion, notificationWorkflow owner
CLI-started executionNoVerify command/deployment pathInitiation and retry expectationOperator
Evaluation runSeparate limitVerify setting and placementLicense tier and test dataEvaluator
Waiting / resumed executionDo not assumeInspect resume pathAge, persistence, cancellationWorkflow owner
Retry queued itemNot supported in captured N11Verify release behaviorDocument operator responseOperator

sum(each worker's chosen concurrency) is only a configured parallel-job ceiling signal, not throughput, safe utilization or capacity.

Shared-state, storage and response-relay boundaries

Redis, database and the same instance key

Workers and webhook processors need access to Redis, the supported shared database and the same instance encryption key as main. Queue mode as a distributed system is not supported over SQLite; the queue guide says running queue mode with SQLite is not recommended. Review Article 4 for database support and backup coverage, and Article 9 for key custody and distribution.

The guide's Redis demo uses port 6379 and no password by default; this is not a production design. Use authenticated Redis on a protected private path. Never expose unauthenticated Redis or DB publicly. A listening port does not prove credentials, schema, key agreement or workflow correctness. Article 5 owns the service manifest.

Binary persistence versus versioned response offload

Keep the scope split. Ordinary binary persistence in queue mode: n8n says filesystem mode is unsupported; use a supported alternative for the selected release. Large queued webhook response offload is a narrower exception: a selected release may use filesystem storage if every instance mounts the same disk, a layout n8n does not recommend. Neither statement cancels the other.

This distinction matters because a worker can write an ordinary binary item that another process later needs to read, while response offload temporarily stores a particular large response so main can stream it to the waiting client. A normal local disk on each host is not shared storage. The captured docs say only main on n8n 2.34.0 or later reads an offloaded body; upgrade main and webhook instances first, then enable offload on workers. Confirm these exact rules against the selected release before use.

Data pathDocumented boundaryDecision / owner
Ordinary workflow binary persistence in queue modeFilesystem mode unsupported; n8n points to external storageSelect a supported release-specific mode and test read-after-write across instances; Article 4 owns retention/artifacts
Large webhook response relaySelected release supports offload; captured requirement includes main/webhook at least 2.34.0 and worker settingTest body read and delivery, deletion and client outcome; do not generalize to all binaries
Shared filesystem for that response pathEvery instance must mount same disk; n8n does not recommend this arrangementPrefer documented S3/Azure option where suitable; external-storage edition and cost are separately verified
Separate local disk per host or unsupported modeCannot establish consistent cross-instance readReject until supported shared path and acceptance evidence exist

Relay memory and graceful shutdown inputs

Queued webhook responses use N8N_WEBHOOK_RESPONSE_RELAY_SIZE_MAX, documented default 64 MiB. The guide estimates about 1.5× the relay cap per in-flight response in Redis. This is only for that relay path, not worker RAM or a general payload budget. MCP Trigger results have a related limit but cannot use this offload path in the captured docs.

Graceful shutdown defaults to 30 seconds, a timing input rather than a completion guarantee. Record long-run duration and drain cutoff. Optional /healthz and /healthz/readiness require QUEUE_HEALTH_CHECK_ACTIVE; they do not prove correct workflow output.

Find the actual constraint with a resource worksheet

Compare equivalent windows before/after, separating observed demand, configured limits and provider allocations. Mark unknowns plainly: worker count hides queue age, execution mix, DB pressure and workflow data memory.

Observation fieldBefore-change recordAfter-change recordInterpretation / owner
Timestamp, window and release/tag________Use matching observation windows; operator
Active production, manual, sub-workflow and evaluation counts________Keep classes distinct; workflow owner
Effective production cap and each worker concurrency________Record env precedence and command flag; operator
Worker count, queued depth and oldest wait age________Do not use queue depth alone as throughput; operator
DB active/available connections and errors________Compare to actual pool/DB limits; DBA/operator
Redis health and memory observation________Include relay only where applicable; Redis owner
Main, worker, runner and host CPU/RAM________Record measured window and process mapping; operator
Payload, binary and response sizes________Separate normal binary from response relay; author
Failures, retries, drain and recovery evidence________Link trace/receipt without secret values; operator

Envelope measured demand for main, webhook processors, workers, matching runners, Redis, DB, proxy and selected services, plus operator-set headroom. Do not call hypothetical maxima an average. Keep execution JSON, Code copies, binaries and manual UI copies separate from request counts; they affect memory.

Unknown DB limits, Redis memory, queue age or payload distribution leave sizing incomplete. Reduce admission, bound jobs, observe shared services, stage one worker or revisit topology. Change one thing with a stop threshold; no arithmetic predicts a VPS size.

Choose an operating path

Choose by observed condition, then verify prerequisites. A component helps only if it relieves the measured constraint without exhausting a shared dependency.

ConditionFirst candidateInventory and observeStop/change whenNext link
Bounded production burst on regular deploymentProduction capProduction arrival rate, FIFO wait and excluded classesManual work or other resources remain unboundedRunbook acceptance below
Manual or heavy data work is the symptomClassify and bound workflow/data; cap alone will not cover itManual copies, Code allocations, payload and durationClass remains unknown or no owner accepts wait behaviorArticle 7 for AI context
Distributed production execution with supported stateRedis queue modePostgres, Redis, key, binary mode, connections and effective concurrencySQLite, public unauthenticated service, key mismatch or unsupported storageArticle 4
Code isolation is the needExternal Code runnerMatching versions, sidecar placement, trust and resource policyRunner topology or secret boundary is unclearArticle 9
Very large webhook responseInspect versioned relay offloadExact version, shared storage and Redis response budgetOlder main, unreadable storage or unsupported binary modeArticle 6
Dedicated webhook processorsEvaluate only with traffic-path requirementsRouting, shared queue port 5678 default, workers and healthRoute ownership or main-pool exclusions are unverifiedArticle 6
Multi-main requirementVerify Enterprise design prerequisitesEdition, session persistence, versions, Postgres and RedisAny requirement or recovery behavior is unverifiedArticle 10
Second host consideredCompare process isolation with placementNetwork, key/state, backup, failure domain and duplicate billablesIndependent recovery and access paths are not provenProvider requirements

A second host adds network and stateful operations; it guarantees neither failover nor recovery. Verify private networking, firewall, backup scope, snapshot/cancellation, renewal, transfer and support at the provider route. Unknowns remain unknown; price selected services with the cost tool.

Change runbook: discover, stage, accept, drain

This bounded acceptance procedure is not an install recipe. It emits no environment values and changes no service. Replace placeholders privately; keep secrets out of shell history, output, tickets and version control.

1. Preconditions and read-only discovery

Identify the owner, selected tag/edition, recovery point, processes and topology. This read-only Bash snippet lists container names, image references and states only. Run on the intended Docker host; non-Docker deployments need an approved inventory method.

#!/usr/bin/env bash
set -euo pipefail

# Read-only inventory. No environment, command, mount, label, or log output.
if ! command -v docker >/dev/null 2>&1; then
  printf '%s\n' 'STOP: Docker CLI unavailable; use the deployment owner’s approved inventory.'
  exit 2
fi
if ! docker info >/dev/null 2>&1; then
  printf '%s\n' 'STOP: Docker daemon is not readable; do not escalate or change access for this check.'
  exit 2
fi
printf '%s\n' 'Container inventory: name | image reference | state'
docker ps -a --format '{{.Names}} | {{.Image}} | {{.State}}'
printf '%s\n' 'STOP after inventory. Resolve each image reference to an approved immutable tag/digest in the deployment record.'

Check protected configuration and secret manager without copying values. Record key presence, owner, rotation date and shared delivery result only. Never print environment or unredacted inspect output. Record DB/Redis as private service identifiers, not credentials.

Discovery fieldRecord without secret valuesStop if
Selected n8n tag, release notes, migration reportREPLACE_WITH_REVIEWED_N8N_VERSION; source links; channel statusTag or 3.0 status/channel conflict unresolved
Edition, deployment shape and each processMain / worker / webhook / runner count and placementUnknown process owner or incompatible version
Effective concurrencyProduction variable present? value privately reviewed; worker flag chosen valuePrecedence or execution class unclear
DB, Redis and key pathSupported DB/version, protected endpoint identifiers, key present and shared?SQLite distributed queue, public listener, missing/mismatched key
Binary and relay behaviorMode, shared-storage design, selected release, body test planUnsupported filesystem assumption or untested offload path
Observed resource baselineWorksheet window, thresholds and data ownerNo DB/Redis or resource stop threshold

2. Recovery gate and design record

Confirm a recoverable backup for DB and artifacts: database, .n8n, key, external binary data and deployment configuration may differ. Check coverage in Article 4 and restore acceptance in Article 10. Do not bundle a major migration.

Complete this operator record before a staged change. Values below are placeholders or operator choices, not recommendations. Store secret values only in the approved secret system; actual .env remains outside version control and logs.

Change ID: REPLACE_WITH_CHANGE_ID
Selected n8n tag/digest: REPLACE_WITH_REVIEWED_N8N_VERSION
Matching release notes + migration report checked by: REPLACE_WITH_OWNER
Chosen path: REPLACE_WITH_REGULAR_CAP_OR_QUEUE_OR_RUNNER
Production cap: REPLACE_WITH_OPERATOR_CHOICE_OR_UNSET
Worker --concurrency: REPLACE_WITH_OPERATOR_CHOICE_OR_NOT_APPLICABLE
Effective precedence reviewed: REPLACE_WITH_YES_NO
Database and Redis private service IDs: REPLACE_WITH_PRIVATE_IDS
Same instance key delivered to required processes: REPLACE_WITH_SECRET_CHECK_RESULT
Binary mode and response relay policy: REPLACE_WITH_REVIEWED_POLICY
Runner version/placement, if selected: REPLACE_WITH_MATCHING_VERSION_AND_MAP
Baseline window / DB and Redis thresholds: REPLACE_WITH_MEASURED_VALUES
Recovery artifact and restore owner: REPLACE_WITH_RECOVERY_RECORD
Admission stop owner / queue cutoff / rollback target: REPLACE_WITH_APPROVED_PLAN

Validate release semantics first. Map matching runner sidecars to required workers and verify manual-run placement. Keep Redis/DB private and authenticated; deliver the same instance key without recording it. Startup order or an open socket does not prove end-to-end readiness.

3. One bounded staged change and acceptance

Change one variable at a time in isolated staging with harmless workflows, using the operator's selected-release procedure.

  1. Record before measurements for equivalent observation windows. State the expected change: which class should wait, execute, or use a runner, and which shared resource must remain below its operator threshold.
  2. Apply the reviewed configuration in staging. Confirm all component tags match and required services are private and authenticated. Do not assume startup order proves readiness.
  3. Verify the intended worker registration or optional health/readiness probe. If health checks are enabled, understand that the endpoints only indicate process and DB/Redis readiness.
  4. Run a harmless production-trigger workflow plus separate manual, sub-workflow, error and CLI cases only where relevant. Confirm each path matches the selected-release behavior record; check FIFO admission, queued cancellation/retry expectations and restart requeue behavior.
  5. Verify workflow result persistence and credential decryption through each required process without exposing credential values. Confirm DB connection use, Redis memory, main/worker/runner RAM and CPU remain inside recorded thresholds.
  6. For response offload, use a non-sensitive test response at a bounded size; verify worker write, main read, client body and cleanup. Test ordinary binary persistence separately. Do not infer one passing path from the other.
  7. Compare after measurements with the same observation window and record failures, queue age and resource deltas. Accept only if the intended class behaves correctly, dependencies remain healthy and the owner signs the receipt.

Acceptance receipt: selected tag and sources ____; topology/process map ____; class-by-class outcome ____; effective concurrency ____; DB connection peak/threshold ____; Redis memory/threshold ____; main/worker/runner resource window ____; key verification result (no value) ____; binary and response tests ____; result persistence ____; operator and workflow-owner sign-off ____.

4. Drain, stop and rollback branch

No universal drain command or job checkpoint guarantee exists. Before a window, document how this deployment stops admissions, inspects work without deleting it, and decides whether long jobs finish or terminate. Record cutoff and accepted loss. If the selected-release procedure is not rehearsed, stop.

Stop immediately on mismatched versions or keys, public unauthenticated DB/Redis, unexpected retries or lost results, unsupported binary storage, rising DB connection exhaustion, Redis or memory threshold breach, failed key decryption, or inability to account for in-flight work. Keep the last known-good topology and artifacts intact.

  1. Stop new admissions using the deployment's reviewed operational control; record the time and queue state. Do not improvise a database edit or delete jobs to make the queue appear empty.
  2. Allow in-flight work to finish only until the approved cutoff and only if its effects are understood. Record remaining work and owners; do not claim graceful shutdown timeout guarantees completion.
  3. If acceptance fails, restore the prior compatible configuration and component set using the approved change procedure. Restore database and artifacts only from the compatible recovery point if required; never combine a new data format with an old runtime without a verified migration path.
  4. Before reopening admissions, verify the prior main/worker, DB, Redis, key and binary path; run a harmless representative workflow and confirm result persistence. Reconcile queued and externally triggered work with workflow owners.
  5. Attach the receipt, unresolved items and exact cutoff to the change record. Send additional host/process/storage requirements to Article 2 and provider terms to the evidence-backed provider route.

This branch links to Article 10 for export, migration and recovery boundaries. Exports are not a substitute for an accepted database-and-artifact restore; do not attach a recovery time or loss guarantee unless your own tested plan supplies it.

Sources and updates

Primary n8n documentation captures checked 2026-11-06. Recheck version-sensitive behavior against the selected tag before changing a deployment.

Captures do not establish the current release; resolve the n8n 3.0 status conflict at selection. No deployment, restore, load test, server change, performance check or provider quote was performed. See Methodology.