# Using 'setTimeout' and restart flow

**URL:** <https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620>\
**Category:** General\
**Created:** [11 June 2024 11:12 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620 "2024-06-11T11:12:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 11:12 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/1 "2024-06-11T11:12:34Z")

</div>

Is an activ `setTimeout` still being executed after a flow restart at the specified time, or is the action 'lost'?

This is the part within a function node:

```auto
    var timerId = setTimeout(function () {
        var msg2 = {
            info: "Timer elapsed!",
            time: nexttime,
            payload: device,
            status: status
        };
        node.send([null, msg2]); // at 'time' send command to device via output 1 (mqtt)
    }, elapsTime);

    msg.payload = (` Next ${nexttime}: ${device} ${status}`);

```

`setTimeout` also returns a parameter with Nodered (here `timerId`) with which the timeout can be canceled. But does this also work after the flow has been restarted, for example?

The `timerID` would be stored in a context variable and could be queried on restart. But does the `clearTimeout(timerId)` reach the operating system for execution?

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [11 June 2024 11:26 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/2 "2024-06-11T11:26:30Z")

</div>

What exactly do you mean by flow restart?

---

<div class="post-metadata">

**Author:** ![voltkj](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/voltkj/32/91879_2.png) [@voltkj](https://discourse.nodered.org/u/voltkj)\
**Post date:** [11 June 2024 11:49 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/3 "2024-06-11T11:49:38Z")

</div>

n Node-RED, the timer identifier (`timerId`) returned by `setTimeout` is only valid for the duration of the flow session. When the flow is restarted, all previously set timers are reset, and the timer identifiers become invalid. Therefore, while you can store the `timerId` in a context variable, calling `clearTimeout(timerId)` after a flow restart will not be effective because the timer associated with that identifier no longer exists.

If you need to manage timers across flow restarts, consider saving the timer state (like the remaining time until execution) in a persistent context variable or an external database. After restarting the flow, you can read this state and set up the timer again with a new `timerId`. This approach requires additional logging and state management, but it can ensure continuity in applications where this is critical.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [11 June 2024 11:55 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/4 "2024-06-11T11:55:50Z")

</div>

If node-red is actually restarted (process ends/restarts) no timers will survive.

What you are facing is the perfect argument for use the tools provided - i.e. the delay or trigger node.

I would recommend you try to breakdown your work into logical blocks and as such create more "low-code" flows that utelise the delay/trigger nodes. In doing so you will not need to maintain timer handles or anything like that. PS, you can cancel a delay/timer node by sending a `{reset:true}` message to it.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [11 June 2024 11:57 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/5 "2024-06-11T11:57:49Z")

</div>

> [@gNeandr](#):
>
> Is an activ `setTimeout` still being executed after a flow restart at the specified time, or is the action 'lost'?

To be clear and to add to what others have said, when Node-RED is restarted ALL context is lost except whatever has been persisted to a file and then reloaded (which happens automatically with persisted context variables - though watch out for the default save timeout, I think it only happens every 30s by default, it can be changed).

However, if you are meaning when a (re)deploy is done, then it depends on the TYPE of deploy. Some are more destructive than others.

---

<div class="post-metadata">

**Author:** ![voltkj](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/voltkj/32/91879_2.png) [@voltkj](https://discourse.nodered.org/u/voltkj)\
**Post date:** [11 June 2024 12:05 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/6 "2024-06-11T12:05:07Z")

</div>

Thank you for the clarifications and valuable suggestions. It seems that using built-in Node-RED nodes like delay and trigger nodes might be a more robust solution for managing timers, especially since they handle restarts more gracefully. This approach of breaking down work into logical blocks and utilizing these nodes will likely simplify flow management without the need to manually maintain timer handles.

Regarding the persistence of timers through restarts and deploys, your explanation helps a lot. I now understand that all timers and context are lost during a restart unless they have been saved and reloaded from a file (which happens automatically with persisted context variables - though watch out for the default save timeout, which is every 30 seconds by default but can be changed).

As for the behavior of `setTimeout` after a flow restart, it depends on the type of deploy. Some deploys are more destructive than others.

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 12:34 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/7 "2024-06-11T12:34:33Z")

</div>

Thanks a lot guys.  
This reminder is probably very important

> [@TotallyInformation](#):
>
> when Node-RED is restarted ALL context is lost except whatever has been persisted to a file and then reloaded

It is probably cleaner to model the required timeout with

> [@Steve-Mcl](#):
>
> delay/trigger nodes

Can anyone point to comparable solutions?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [11 June 2024 12:45 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/8 "2024-06-11T12:45:39Z")

</div>

What are you actually trying to achieve?

Are you actually wanting a timeout that actually survives a node-red restart?

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 13:10 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/9 "2024-06-11T13:10:07Z")

</div>

Here is a brief project outline:  
Throughout the day, (mqtt) jobs must be executed at daily recalculated times. A list holds these time-defined jobs and is processed one after the other. If a job is executed, the time span to the next job time is calculated and executed as a 'timeout'.

If a pending job is canceled (by the user), the next job in the list should be executed at the correct time. The old 'timeout' of the canceled job may no longer be executed.

On the other hand, an interruption/cancellation of the flow should not result in pending jobs being lost on restart.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [11 June 2024 13:15 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/10 "2024-06-11T13:15:58Z")

</div>

Seems to me you need to persist the job queue not the time out.

There are a few ways to skin that cat but here are 2 off the top of my head.

1. Job list entries are an array of { executionTime, jobDetails } & are stored in [persistent context](https://nodered.org/docs/user-guide/context)
2. A regular inject set to run every 1m (or so) checks the list for any jobs to execute

Alternatively,

1. Install [node-red-contrib-cron-plus](https://flows.nodered.org/node/node-red-contrib-cron-plus)
2. As jobs arrive, generate a new schedule and add it to a cron node (one which has "persist schedules" enabled)

_the cron node has built in examples `ctrl-i` -\> examples_

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 13:33 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/11 "2024-06-11T13:33:41Z")

</div>

Since the list of jobs with their times is stable over the day, I would follow your first suggestion point 1. The list will be available as a file.  
But in my opinion, the best way to process it is "from job to job".

In any case, the restart, or manual delete a pending job, the flow has to find the next job on the list using the the current time and compare with the list. So it calculates the time gap from 'now' to the next job time and finally executes the 'timeout' (delay or whatever).  
I will try with the 'delay' node.

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 15:24 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/12 "2024-06-11T15:24:22Z")

</div>

Another question about node 'delay'

Do I understand correctly that the `delay` node collects the messages and thus manages several messages? This means that a new incoming message will not overwrite/delete previous ones.

Only when the `delay` for a message has expired is it forwarded and removed from the delay stack.  
Alternatively, the entire stack can be deleted with

> [@Steve-Mcl](#):
>
> `{reset:true}`

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [11 June 2024 15:33 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/13 "2024-06-11T15:33:06Z")

</div>

> [@gNeandr](#):
>
> Do I understand correctly that the `delay` node collects the messages and thus manages several messages? This means that a new incoming message will not overwrite/delete previous ones.

Yeah.

As the built in help says "Delays each message passing through the node"

Emphasis on **each**

  

> [@gNeandr](#):
>
> Only when the `delay` for a message has expired is it forwarded and removed from the delay stack.

Correct

  

> [@gNeandr](#):
>
> Alternatively, the entire stack can be deleted with
> 
> > [@Steve-Mcl](#):
> >
> > `{reset:true}`

Yeah.

The built in help says better:

> `reset`  
> If the received message has this property set to any value, all outstanding messages held by the node are cleared without being sent.

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 17:18 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/14 "2024-06-11T17:18:59Z")

</div>

Thanks @ [Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)

Working with node `delay` and using `{reset:true}` does the job! 👍

_ **Great help!** _

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [11 June 2024 18:39 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/15 "2024-06-11T18:39:35Z")

</div>

Could you use node-red-contrib-cron-plus? That allows loading of schedules dynamically.

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 21:03 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/16 "2024-06-11T21:03:35Z")

</div>

Interesting advice. But as far as I can see, it doesn't fit into the required user concept.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [11 June 2024 21:20 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/17 "2024-06-11T21:20:23Z")

</div>

Probably I misunderstand the requirement. I thought that at some point you determine a schedule of tasks to be performed at given times during the day. Having determined that you could pass the schedule to the cron plus node and leave it to it.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [11 June 2024 22:13 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/18 "2024-06-11T22:13:11Z")

</div>

> [@Colin](#):
>
> Could you use node-red-contrib-cron-plus?

That would also be my suggestion.

---

<div class="post-metadata">

**Author:** ![gNeandr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gneandr/32/73947_2.png) [@gNeandr](https://discourse.nodered.org/u/gNeandr)\
**Post date:** [11 June 2024 22:27 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/19 "2024-06-11T22:27:58Z")

</div>

As previously mentioned, the above settime task description only shows part of the project.

The user should see the daily list in order to be able to make various changes to the jobs during the day. These parts of the project are largely realized. I fear that much of this will have to be changed again with using node-red-contrib-cron-plus  
Nevertheless, thanks for the suggestion 👍

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [9 September 2024 22:28 UTC](https://discourse.nodered.org/t/using-settimeout-and-restart-flow/88620/20 "2024-09-09T22:28:34Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
