AutomationFlowsGeneral › Distribute Workflow Execution with Round-robin Logic Using Data Tables

Distribute Workflow Execution with Round-robin Logic Using Data Tables

ByAdrian Kendall @akendall1966 on n8n.io

Implements a simple round-robin distribution mechanism using a Data Table to track the last route used.

Event trigger★★★★☆ complexity12 nodesData Table
General Trigger: Event Nodes: 12 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #10048 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "Ec7D7cmLxrh1z03H",
  "name": "Load Balancer",
  "tags": [],
  "nodes": [
    {
      "id": "37cad4dc-4a5e-4e32-9472-af8f3eb99e2e",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -432,
        -48
      ],
      "parameters": {},
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "2f22a244-b3d4-429e-aa3b-b0cf70d04553",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        32,
        40
      ],
      "parameters": {
        "jsCode": "// Get the input data\nconst items = $input.all();\n\n// Process each item\nreturn items.map(item => {\n  const currentValue = item.json.Last_Used;\n  \n  // Increment by 1, or reset to 0 if current value is 3\n  const newValue = currentValue === 3 ? 0 : currentValue + 1;\n  \n  // Return only the required fields\n  return {\n    json: {\n      Last_Used: newValue,\n      id: item.json.id\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "b7b808a8-68b6-4cf4-8a29-4127cfc9a295",
      "name": "Route 2",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1024,
        -64
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "62130582-657d-4e72-abf7-6b3aa41ca7d7",
      "name": "Round Robin Router",
      "type": "n8n-nodes-base.switch",
      "position": [
        704,
        -48
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "97d76b5a-e6c0-40a8-9ddc-7007078b3cea",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.Last_Used }}",
                    "rightValue": 1
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cdc26adb-91ea-4195-b3b0-d33b8405f048",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.Last_Used }}",
                    "rightValue": 2
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "1b161918-6d41-4fc9-8e61-a8aaf000348c",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.Last_Used }}",
                    "rightValue": 3
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": 0
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "021aea98-1458-4c1c-8d63-c1db8f6619d8",
      "name": "Route 1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1024,
        -224
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ab72a82d-bed2-4541-a440-b557b9bb27bf",
      "name": "Route 3",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1024,
        96
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b9a2d1bc-c6ed-48ac-9f81-9b92448a4c0a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -256
      ],
      "parameters": {
        "height": 432,
        "content": "## Merge Input \nIf your using a trigger that passes some data to process you can merge it."
      },
      "typeVersion": 1
    },
    {
      "id": "679c6ecd-4f29-42da-a3ea-2389cea5612c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        -256
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 672,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Link to sub-workflows\nReplace these do nothing nodes with links to your duplicates of the workflows to call"
      },
      "typeVersion": 1
    },
    {
      "id": "7ceb2c37-5f0a-443b-8845-53e368b5b04f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        192
      ],
      "parameters": {
        "color": 5,
        "width": 1328,
        "height": 224,
        "content": "## Round Robin Load Balancer\nIf you have got a workflow that is getting called frequently. A common way to scale the service is to duplicate resources and have a load balancer that distributes the work between the resources.  A simple form is to use a round robin approach that cycles round the available resources.\nThis workflow mimics that approach using a datatable to track the last resource used and the next time its triggered that instance get routed to the next output of a switch node.  For production use replace the no action node with workflow or a subworkflow node.\nIn reality I understand N8N can spawn multiple workers in the backend so can parallel process the same workflow multiple times so this is likely an over the top approach from most use cases. "
      },
      "typeVersion": 1
    },
    {
      "id": "fd648340-f444-40bf-ae4c-311bed19118c",
      "name": "Calculate the next route to use",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        -192,
        40
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyValue": "1"
            }
          ]
        },
        "matchType": "allConditions",
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "l3AW3b12ncdHyI35",
          "cachedResultUrl": "/projects/BoXbNP1BVNpuJKk6/datatables/l3AW3b12ncdHyI35",
          "cachedResultName": "Load Balancer"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "699d30f1-89ce-42a1-bcaa-567e4b2330c1",
      "name": "Update last_used in the datatable",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        256,
        40
      ],
      "parameters": {
        "columns": {
          "value": {
            "Last_Used": "={{ $json.Last_Used }}"
          },
          "schema": [
            {
              "id": "Last_Used",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Last_Used",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Last_Used"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyValue": "1"
            }
          ]
        },
        "options": {},
        "matchType": "allConditions",
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "l3AW3b12ncdHyI35",
          "cachedResultUrl": "/projects/BoXbNP1BVNpuJKk6/datatables/l3AW3b12ncdHyI35",
          "cachedResultName": "Load Balancer"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "63736019-79a6-4bfe-a2ff-670d1ef46f91",
      "name": "Merge trigger data to pass to subworkflow if needed",
      "type": "n8n-nodes-base.merge",
      "position": [
        480,
        -32
      ],
      "parameters": {},
      "typeVersion": 3.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e0b005ce-f1ca-4b28-8053-21828bd1d44f",
  "connections": {
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Update last_used in the datatable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Round Robin Router": {
      "main": [
        [
          {
            "node": "Route 1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Route 2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Route 3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate the next route to use": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update last_used in the datatable": {
      "main": [
        [
          {
            "node": "Merge trigger data to pass to subworkflow if needed",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Calculate the next route to use",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge trigger data to pass to subworkflow if needed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge trigger data to pass to subworkflow if needed": {
      "main": [
        [
          {
            "node": "Round Robin Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Implements a simple round-robin distribution mechanism using a Data Table to track the last route used.

Source: https://n8n.io/workflows/10048/ — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

General

Agendamiento. Uses n8n-nodes-evolution-api, redis, dataTable, executeWorkflowTrigger. Event-driven trigger; 60 nodes.

N8N Nodes Evolution Api, Redis, Data Table +2
General

This workflow provides a reusable error handling, audit logging, and observability pattern for n8n workflows using two n8n custom Data Tables: and .

Error Trigger, Data Table, Execute Workflow Trigger
General

If you're in need of a quick and dirty cache that doesn't need anything other than the current version of N8N, boy do I have a dodgy script for you to try!

Execute Workflow Trigger, Data Table, Stop And Error
General

send_image. Uses executeWorkflowTrigger, dataTable, n8n-nodes-evolution-api-english, httpRequest. Event-driven trigger; 5 nodes.

Execute Workflow Trigger, Data Table, N8N Nodes Evolution Api English +1
General

tableToSheet. Uses executeWorkflowTrigger, dataTable, googleSheets. Event-driven trigger; 3 nodes.

Execute Workflow Trigger, Data Table, Google Sheets