How to keep one instance running continuously?

Hi - how can I keep one workflow running continuously? My goal is to keep two data sources always approximately in sync (within a minute or so).

Meaning,

  • it should keep running in a continuous loop, without stopping
  • if it does stop for some reason, upon restarting the server, ideally it would restart.
  • I’ll build in delays etc so there’s no worry about DDOSing myself
  • I don’t mind manually starting the workflow after a restart, if that’s the only time it needs to be manually started. It seems like if I close my browser tab after starting the execution, it does keep running…

If I create a Cron to run the process every X minutes, is there a way to prevent it from running multiple processes in parallel, if one is already running?

I imagine I could track the start time of each execution and then force it to stop after 55 seconds, and then launch a new Cron every 60 seconds. Is there a better way though?

Thank you!

Hey @Byron,

Can you not achieve this using Webhooks? This will trigger your workflows when an external event occurs. You won’t have to keep your workflow running continuously.

Something like this should help you with structuring your workflow to have only one instance of it running, at a time.

{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        290
      ]
    },
    {
      "parameters": {
        "interval": 30
      },
      "name": "Interval",
      "type": "n8n-nodes-base.interval",
      "typeVersion": 1,
      "position": [
        250,
        460
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{  $json.continue  }}",
              "value2": true
            }
          ]
        }
      },
      "name": "New execution?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        550,
        460
      ]
    },
    {
      "parameters": {},
      "name": "NoOp",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        740,
        580
      ]
    },
    {
      "parameters": {},
      "name": "NoOp1",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1330,
        330
      ]
    },
    {
      "parameters": {
        "functionCode": "const staticData = getWorkflowStaticData('global');\nstaticData.workflowRunStatus = false;\n\nitems[0].json = {message: 'Now stopping'};\nreturn items;\n"
      },
      "name": "Workflow End",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1170,
        330
      ]
    },
    {
      "parameters": {
        "functionCode": "const staticData = getWorkflowStaticData('global');\nconst workflowRunStatus = staticData.workflowRunStatus;\n\nif(workflowRunStatus) return [{json:{continue: false,message: 'Already running'}}];\n\nstaticData.workflowRunStatus = true;\n\nitems[0].json = {continue: true,message: 'Now running'};\nreturn items;"
      },
      "name": "Workflow Start",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        400,
        460
      ]
    },
    {
      "parameters": {
        "amount": 150,
        "unit": "seconds"
      },
      "name": "Your code/nodes",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "position": [
        760,
        330
      ],
      "webhookId": "6c2a9b5a-99d1-4d1a-b0bb-e5ce4317b658"
    }
  ],
  "connections": {
    "Interval": {
      "main": [
        [
          {
            "node": "Workflow Start",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New execution?": {
      "main": [
        [
          {
            "node": "Your code/nodes",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "NoOp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow End": {
      "main": [
        [
          {
            "node": "NoOp1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Start": {
      "main": [
        [
          {
            "node": "New execution?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Your code/nodes": {
      "main": [
        [
          {
            "node": "Workflow End",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Here, the workflow is simulating an execution of your logic, using the Wait node (waiting for 150 seconds).
While, it’s being triggered to run every 30 seconds, using the Interval trigger node.

As seen from the log, while Execution ID 1519 is running (waiting for 150 seconds), all subsequent executions get stopped soon after starting, and without executing any of the relevant code/nodes.

3 Likes

Hi Shrey - thank you SO much for the thoughtful and helpful reply! This makes sense and I agree this should work in cases where my workflow has “normally” stopped itself and thus set the runstatus to false.

However, I’m not sure this is solving my issue, but I could be missing something. I can already create an infinite loop so that my workflow in theory should never stop (using the wait timer). I’m more concerned about situations where my workflow crashed unexpectedly. In these cases, I think your code would never set the runstatus to false?

It seems there is no way to check if something is “currently running”? If no, I could probably use your code in combination with some last-run-timestamps from my side…

Thank you!

1 Like

You can also check out this workflow:

It uses the internal API to check if an instance of workflow is already running.

1 Like

This solved my problem perfectly, thank so much Jan!

Great to hear. Have fun!