N8n Kubernetes Queue Mode: Jobs Not Distributed Across Multiple Workers (HPA/Scaling Not Working)

Hi all,

I’m running n8n (Enterprise) in Kubernetes using the official Helm chart with queue mode enabled and Valkey (Redis-compatible) as the backend. My goal is to have multiple worker pods process jobs in parallel for scaling, but all jobs are being processed by a single worker, even when I submit a large batch (e.g., 50 jobs).

My setup:

  • n8n main, worker, and webhook pods deployed via Helm

  • queue.bull.redis.host points to a working Valkey instance

  • EXECUTIONS_MODE=queue and N8N_RUNNERS_ENABLED=true

  • Worker section in values.yaml:

    worker:
      enabled: true
      concurrency: 5
      replicaCount: 1
      autoscaling:
        enabled: true
        minReplicas: 2
        maxReplicas: 4
        targetCPUUtilizationPercentage: 70
        targetMemoryUtilizationPercentage: 80
      resources:
        limits:
          cpu: 2000m
          memory: 2Gi
        requests:
          cpu: 500m
          memory: 512Mi
    
  • Scaling worker deployment manually (e.g., to 3 pods) still results in all jobs being processed by a single worker pod (same execution/worker ID in workflow output)

Kindly suggest what needs to be done in such case

1 Like

Hi @akshika.sharma

In n8n, a Loop Node (or a single trigger with 50 items) creates one single execution ID. That single ID is assigned to one worker.That worker processes all 50 items internally. It does not push individual loop iterations back to Redis for other workers to steal.

check this:

  • Verify Triggers: Ensure you are creating 50 separate workflow execution IDs in Redis, not one execution with 50 items.

  • Break the Chain: If using sub-workflows, switch from the Execute Workflow node to the HTTP Request → Webhook pattern to force n8n to generate a fresh execution ID for every single call

  • Check Logs: * Run kubectl logs -l app=n8n-worker --all-containers=true -f and watch all 3 pods.

  • Trigger your batch.

  • Test: Temporarily set concurrency: 1 in your values.yaml. This forces the “busy” worker to reject new jobs immediately, proving instantly if the other pods are connected and able to pick up the overflow.