{
  "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
          }
        ]
      ]
    }
  }
}