# Performance get/set variables. different methods

**URL:** <https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357>\
**Category:** General\
**Tags:** function-node\
**Created:** [29 January 2023 15:33 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357 "2023-01-29T15:33:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 15:33 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/1 "2023-01-29T15:33:30Z")

</div>

Hello,

I have a performance question.  
There are multiple methods of getting and setting variables. I would like to know what is adviced, or what gives the best performance between them.

### Question 1: what method is adviced:

Method 1: single call  
var example1 = global.get('storedvariable1',"file");  
global.set per variable.

Method 2: multi call  
var values=flow.get(["v1","v2"]);  
var v1=values[0];  
var v2=values[1];

But... method 2 can also be in the form like this:

```auto
MQTT.block_active
MQTT.allow_rtc_onoff
MQTT.allow_scheduler
MQTT.allow_solar
MQTT.block_mode
MQTT.message_limit
MQTT.counter
MQTT.messages_yesterday
MQTT.messages_today
MQTT.block_mode_previous

```

Calling variable MQTT  
`var MQTT = global.get('MQTT', "file");`

In this example, it could be in reality that I only require 2 variables from MQTT in the function after reading.

The questions are:  
Q1: what method of getting variables would be best for performance.  
Q2: Using method 2 in the form I wrote in the example, would loading the extra variables result in a performance thing?

### Store to file vs memoryOnly:

I use 2 storage methods. for live values only use memoryOnly, and for storing graphs or settings store in 'file'.  
The settings have a flush timer of 300 seconds.

Q3: when global.getting a variable from "file", does that mean there is a read action done?

Q4: When setting a global variable to 'file' location, does the variable store DIRECTLY to file/disk, or collect it during 300 seconds, and THEN store it to file?  
For the amount of writing actions.. I can see there is a significant performance topic here in case the actual writing is done instantly instead of once per 300 seconds.  
The things I have read still leave me with this question. I THINK the flush timer is collecting all changed variables and writing it once 300 seconds. But I'd like this confirmed 🙂

Many thanks for all the support here.  
Great forum.

Kind regards,

---

<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:** [29 January 2023 15:53 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/2 "2023-01-29T15:53:42Z")

</div>

> [@edterbak](#):
>
> I have a performance question.  
> There are multiple methods of getting and setting variables. I would like to know what is adviced, or what gives the best performance between them.

Why? Are you hitting a bottleneck of some kind? If not, then dont worrry (see [premature optimisation is the root of all evil](https://www.google.com/search?q=premature+optimization+is+the+root+of+all+evil+xkcd&tbm=isch) 😉 )

Your Methods 1 and 2 are pretty much the same in terms of code execution however, there is a 3rd way that is definitely faster...

```auto
const example3 = flow.get('myData') || {} // Get 1 flow context variable (or new new {} is empty)
let storedVar1 = example3.storedVar1
let storedVar2 = example3.storedVar2
// ...
let storedVar98 = example3.storedVar98

let aNewStoredVar99 = storedVar1 + 1
let aNewStoredVar100 = storedVar2 + storedVar3
example3.storedVar99 = aNewStoredVar99
example3.storedVar100 = aNewStoredVar100
flow.set('myData', example3) // Update 1 flow context variable

```

In other words, you get / set an object that contains all of you stored values.

  

> [@edterbak](#):
>
> Q1: what method of getting variables would be best for performance.

See above

> [@edterbak](#):
>
> Q2: Using method 2 in the form I wrote in the example, would loading the extra variables result in a performance thing?

See above

> [@edterbak](#):
>
> Q3: when global.getting a variable from "file", does that mean there is a read action done?

No. Data stored in the file is loaded (cached) in memory upon starting node-red. Each subsequent `get` and `set` is done against the in-memory cache

> [@edterbak](#):
>
> Q4: When setting a global variable to 'file' location, does the variable store DIRECTLY to file/disk, or collect it during 300 seconds, and THEN store it to file?

Values are written to the in-memory cache & after the configured time, they are flushed to file.

---

<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:** [29 January 2023 16:57 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/3 "2023-01-29T16:57:27Z")

</div>

I think that, in the past, we discovered that even if you try to load a specific property from a context variable object, the whole object gets loaded to memory anyway and so there are no benefits to trying to get just a single part of an object variable. Since JavaScript objects are passed by reference and not by value, assigning to another variable is the tiniest of overheads if any.

There is another tweak which can be helpful as well. You can use modern spread methods. In particular syntax such as:

```auto
const {a, b, c} = flow.get('myObject')

```

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 17:23 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/4 "2023-01-29T17:23:42Z")

</div>

Hi, thanks Steve-Mcl

The reason I am asking is that I am now at a point of restructuring the variables I have. There are about 180 of them I load / save. Not all at once, but when they are needed.  
There are groups of variables that kind of belong together.

Now that I am restructuring making things more logical, better to take along the information about performance now, than later run into issues.  
But reading the 2 responses, I see it is not something to worry about.

So; There is no benefit in reading one object containing multiple values vs multiple readings containing 1 variable. (apart from the coding itself)  
Also when looking at the CPU load aspect?

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 17:24 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/5 "2023-01-29T17:24:19Z")

</div>

Thanks TotallyInformation; So basically if you define a list of variables in front of the =, you can pupulate them after the = in the right order.

Nice tip 🙂 Thanks

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 17:36 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/6 "2023-01-29T17:36:50Z")

</div>

> [@Steve-Mcl](#):
>
> No. Data stored in the file is loaded (cached) in memory upon starting node-red. Each subsequent `get` and `set` is done against the in-memory cache

Oh, wait....

Does this also mean there is no benefit of having a variable 'xyz',"file" AND 'xyz',"memoryOnly".  
If the "file" variable is used, there is totally no need to have the same variable in "memoryOnly"?

This would reduce some coding lines anyway 😃

When you confirm this, I have some trimming to do 🙂

---

<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:** [29 January 2023 17:40 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/7 "2023-01-29T17:40:02Z")

</div>

> [@edterbak](#):
>
> There are about 180 of them

Do you really need that many in global context? I very rarely use flow context and virtually never global. Have you considered whether you might be better to restructure some flows to get rid of some of them?

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 17:49 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/8 "2023-01-29T17:49:23Z")

</div>

Well, I do think most are needed. Some I could get away with flow, and also some are required to be in context.

Not meant as an add or something, but the background (usecase) for this:  
I started using NR to communicate with my Panasonic heatpump.  
A lot of nice things to show, set and do. Also I have created custom functions for things which are not present in the panasonic equipement.  
I have shared this project on github. At first I was the only one. Now after two years it grew and it is being used by I think atleast 30 people. But it might as well be more than 100, I cant tell. Kind of nice for an amateur like me. 🙂

> **[GitHub - edterbak/NodeRed\_Heishamon\_control: a Node Red flow to interact with...](https://github.com/edterbak/NodeRed_Heishamon_control)**
>
> a Node Red flow to interact with Heishamon (a panasonic heatpump through an ESP board) - GitHub - edterbak/NodeRed\_Heishamon\_control: a Node Red flow to interact with Heishamon (a panasonic heatpum...

note that I am not happy the way the flow now looks. The GUI needs structuring and polishing to make it intuitive again. But thats my challange.

Anyway;  
By the nature of the project, I require settings to be stored so they are still available after reboot.  
Most variables need to be available on all tabs. Not all. But from my point of view. There is no benefit of setting a flow compared to a global variable.

---

<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:** [29 January 2023 17:56 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/9 "2023-01-29T17:56:54Z")

</div>

> [@edterbak](#):
>
> Does this also mean there is no benefit of having a variable 'xyz',"file" AND 'xyz',"memoryOnly".  
> If the "file" variable is used, there is totally no need to have the same variable in "memoryOnly"?

If you do that they are different variables.

---

<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:** [29 January 2023 17:57 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/10 "2023-01-29T17:57:51Z")

</div>

> [@edterbak](#):
>
> By the nature of the project, I require settings to be stored so they are still available after reboot.

Do you use MQTT?

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 17:58 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/11 "2023-01-29T17:58:10Z")

</div>

different variable, with the same value... sounds to me like "overhead". correct?

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 17:58 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/12 "2023-01-29T17:58:44Z")

</div>

yes, all is done through mqtt.

---

<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:** [29 January 2023 18:02 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/13 "2023-01-29T18:02:30Z")

</div>

> [@edterbak](#):
>
> all is done through mqtt.

In that case you could consider using Retained Topics in MQTT rather than context. It has the big advantage that when data changes you immediately get notified about the change.

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 18:06 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/14 "2023-01-29T18:06:36Z")

</div>

No, Yes.. welll.

I could do that, but I have already trapped into that error that values are retained and incorrect causing issues in the logic.  
I think I am better off using retain false, qos 0 to make sure I have the correct variables.

For me, not fully understanding the effects and the rules regarding to retain messeges, it is the door to hell. ghehehe. 🙂

(the situation I had was that the pump was swittching some settings every couple of minutes due some retained value. After removing the topic, issue was gone. But this is likely my shortcoming)

This would shave off about 30 variables at most. probably less. The rest is in my logic and functions.

---

<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:** [29 January 2023 18:37 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/15 "2023-01-29T18:37:13Z")

</div>

> [@edterbak](#):
>
> So; There is no benefit in reading one object containing multiple values vs multiple readings containing 1 variable. (apart from the coding itself)

Not quite.

Loading and Saving 1 object (full of your variables) is far quicker than calling flow.set or flow.get multiple times. This is due to several layers (plugin, path parsing, value extraction etc).

When you get 1 object, it pulls only the reference from memory (not all of the individual value) so is faster.

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 18:42 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/16 "2023-01-29T18:42:19Z")

</div>

> [@Steve-Mcl](#):
>
> Not quite.
> 
> Loading and Saving 1 object (full of your variables) is far quicker than calling flow.set or flow.get multiple times. This is due to several layers (plugin, path parsing, value extraction etc).
> 
> When you get 1 object, it pulls only the reference from memory (not all of the individual value) so is faster.

This is very usefull. Mega thanks.  
Also nice to read that the derection I was thinking in, looks te be the right one according to your reply.

Thank you for the reply and clear answer.. 🙂

---

<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:** [29 January 2023 20:10 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/17 "2023-01-29T20:10:21Z")

</div>

> [@edterbak](#):
>
> Does this also mean there is no benefit of having a variable 'xyz',"file" AND 'xyz',"memoryOnly".  
> If the "file" variable is used, there is totally no need to have the same variable in "memoryOnly"?

That's right - the file store is really pretty much the same as the memory store but the memory is written to file every NN seconds and read from file on Node-RED startup. (There is actually one really important difference though. When written to file, the data has to be serialised and not everything that JavaScript can store in memory can be serialised. Hence the reason that Node-RED tends to automatically remove the ExpressJS `res` and `req` properties for example).

When you do a `const xx = ....get(....)` from any store, you are simply creating a reference to the memory location.

---

<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:** [29 January 2023 20:16 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/18 "2023-01-29T20:16:49Z")

</div>

> [@edterbak](#):
>
> different variable, with the same value

No, really different variables, that can have different values.

---

<div class="post-metadata">

**Author:** ![Buckskin](https://avatars.discourse-cdn.com/v4/letter/b/b9e5f3/32.png) [@Buckskin](https://discourse.nodered.org/u/Buckskin)\
**Post date:** [29 January 2023 21:15 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/19 "2023-01-29T21:15:30Z")

</div>

> [@TotallyInformation](#):
>
> There is another tweak which can be helpful as well. You can use modern spread methods. In particular syntax such as:
> 
> ```auto
> const {a, b, c} = flow.get('myObject')
> 
> ```

The advantage of this approach is (taking your MQTT Object as an example)

```auto
let {lmessage_limit, allow_rtc_onoff} = flow.get('loadsOfThings').MQTT

```

---

<div class="post-metadata">

**Author:** ![edterbak](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/edterbak/32/60017_2.png) [@edterbak](https://discourse.nodered.org/u/edterbak)\
**Post date:** [29 January 2023 21:58 UTC](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357/20 "2023-01-29T21:58:45Z")

</div>

To write it out completely...

```auto
MQTT.block_active
MQTT.allow_rtc_onoff
MQTT.allow_scheduler
MQTT.allow_solar
MQTT.block_mode
MQTT.message_limit
MQTT.counter
MQTT.messages_yesterday
MQTT.messages_today
MQTT.block_mode_previous

```

getting all variables would be like this:

```auto
let {block_active, allow_rtc_onoff, allow_scheduler, allow_solar, block_mode, message_limit, counter, messages_yesterday, messages_today, block_mode_previous} = global.get( 'MQTT', "file");

```

Correct? or am I interpreting it wrong now 🙂

thank you all guys for the guidance. This stuff will probably speed up the flow and responsiveness, and reduce resource footprint.

[Next page](https://discourse.nodered.org/t/performance-get-set-variables-different-methods/74357.md?page=2)
