# Please help, I have created a Global variable monstrosity that destroys VMs

**URL:** https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617
**Category:** General
**Created:** [23 October 2024 20:48 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617 "2024-10-23T20:48:43Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![no\_mpimpi](https://avatars.discourse-cdn.com/v4/letter/n/f14d63/32.png) [@no\_mpimpi](https://discourse.nodered.org/u/no_mpimpi)
#### Post date: [23 October 2024 20:48 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/1 "2024-10-23T20:48:43Z")

</div>

Hello nice Node-RED peoples,

I have done a bad. I know I have, but I don't know how to not.

So, in an effort to avoid having to learn how to database, I got the idea to just store every incoming MQTT message in a global array; just the current topic and payload. Updates when a new message comes in, overwrites the last payload value per topic.

These are light and switch states, so the payload is usually {"state": true} or {"state": false}, so the data ought to be small. I thought.

My rationale for doing this was that I could then query the current state in code elsewhere. For example, a person has entered the bog. Have they shut the door behind them? They have. Does the distance between the ceiling and the bog seat indicate they are probably sat down? It does. Serious business, then, best start the extractor fan

There I was, so convinced I had been very clever, waltzed away from the keyboard to go and do practical things in the world, and when I came back some hours later, the memory and disc space were maxed, and the spouse was unhappy because nothing was working. To be fair, I was unhappy too.

I run Node-RED in an LXC on Proxmox, with 4GB of RAM and 8GB of drive. I doubled both of these, and watched as they began to fill up over the next few hours. Clearly it's the new code, because when I disable that function, the problem goes away.

It seems, therefore, that I have fundamentally misunderstood how Node-RED manages memory. I don't seem to be updating the global array so much as copying it every time it updates, I think.

There are only 60ish topics, and the array is stable at that size - in other words, it's not just growing and growing.

Here is my stupid function. Please tell me what I am doing wrong. I would prefer to understand this in a way that prevents me from being this wrong again.

If this was a dumb idea from the get-go, I would like to understand why that is, too.

```auto
[{"id":"faa407de87fa8f70","type":"function","z":"c8268b7b6089484d","name":"Shove in a global array","func":"var obj = { // Creates thing we're going to store.\n \"topic\": msg.topic,\n \"status\": msg.payload\n};\nvar states = global.get(\"states\") || []; // If the global \"states\" array doesn't exist, return an empty one.\nvar big = states.length; // Is how we'll know if it's empty\nvar found = false;\nif (big == 0){ // It was empty, so we shove a the new thing into it. Now it's not empty. Yay.\n states.push(obj);\n} else {\n let keys = Object.keys(states); // Fine, it's not empty, so first let's check if we've seen this topic before\n for (let i = 0; i < keys.length; i++) {\n var temp = states[i];\n if (obj.topic == temp.topic){ // Hello old friend.\n found = true; // They were lost, but now they are found. But they're vegetarian, let the goat go.\n temp.status = obj.status; // Update the stored payload with the current one.\n break; // annnnnd stop looking.\n }\n };\n if(found == false){ // If we still didn't find this topic, then its obviously unique, just shove the new thing in,\n states.push(obj);\n };\n};\nglobal.set(\"states\", states); // This might be where the mistake is. Is this the mistake? I feel like it is.\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":870,"y":480,"wires":[[]]},{"id":"5e03e7cd7cf7cdc0","type":"mqtt in","z":"c8268b7b6089484d","name":"","topic":"","qos":"2","datatype":"auto-detect","nl":false,"rap":true,"rh":0,"inputs":0,"x":570,"y":480,"wires":[["faa407de87fa8f70"]]}]

```

I thank you.

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [23 October 2024 21:19 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/2 "2024-10-23T21:19:18Z")

</div>

I'm not sure I understand everything in your function despite all the comments.  
I think you need the context variable as an object not an array.

```auto
var states = global.get("states") || {}

```

Now you can **either** update **or** create an element with the same statement, so no chance of it running out of control.

```auto
states[msg.topic] = msg.payload

```

You can access a value with eg `states.kitchen` (I'm steering clear of your bathroom!)

> [@no\_mpimpi](#):
>
> Does the distance between the ceiling and the bog seat indicate they are probably sat down? It does. Serious business, then, best start the extractor fan

Not only creepy but sexist too! 🤪

---

<div class="post-metadata">

### Author: ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)
#### Post date: [23 October 2024 23:02 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/3 "2024-10-23T23:02:38Z")

</div>

@jbudd 's suggest is sound as it is far simpler to create a global object.

If you really want an array then a function more like this is clearer

```auto
ìf(msg.topic && msg.payload){ // msg.topic and payload exsists, you can also check they are the correct type etc
    const states = global.get("states") || [];    
    const index = states.findIndex(obj => obj.topic === msg.topic); //find index
    if(index >= 0){
        states[index].status = msg.payload; // Update the stored payload with the current one.
    }else{ // If we still didn't find this topic, then its obviously unique, just shove the new thing in,
        states.push({ // create new tyopic state
            topic: msg.topic, 
            status: msg.payload
        });
    };
    global.set("states", states);              
    return msg;
}

```

---

<div class="post-metadata">

### Author: ![no\_mpimpi](https://avatars.discourse-cdn.com/v4/letter/n/f14d63/32.png) [@no\_mpimpi](https://discourse.nodered.org/u/no_mpimpi)
#### Post date: [25 October 2024 03:30 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/4 "2024-10-25T03:30:41Z")

</div>

Hi @jbudd,  
Thank you for your code suggestions.

> [@jbudd](#):
>
> Not only creepy but sexist too! 🤪

None of the genders that live in my house stand up to take a dump. You do you, though, I'm not judging. 😆

For me, a toilet is a very good candidate for automation, especially if you have kids. I didn't even mention the little servo that squeezes a shot of airfreshener when user is done.

The goal, you see, is to have a house that reacts and predicts, such that I never have to touch a switch.

Anyway, your help is appreciated.

---

<div class="post-metadata">

### Author: ![no\_mpimpi](https://avatars.discourse-cdn.com/v4/letter/n/f14d63/32.png) [@no\_mpimpi](https://discourse.nodered.org/u/no_mpimpi)
#### Post date: [25 October 2024 03:36 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/5 "2024-10-25T03:36:17Z")

</div>

Hi @E1cid,

Thank you for your code suggestion. If you have second, could you please clarify why you'd use **const** instead of **var**? Assume a strong level of ignorance on my part.

In any case, it turns out that the problem (probably) had nothing to do with the code.

The CMOS battery on the motherboard of the little machine I use as a server had died, resulting in no way to keep the real time. This meant that the system log began to grow with errors at a crazy rate, and filled the drive with a colossal log file which caused everything to explode.

I figured this out when time-based automations began to malfunction, and an attempt to recreate the node-red docker container was refused because of ... a time-based error, I forget what the actual message was.

Let me tell you, replacing a CMOS battery on an Intel NUC is no laughing matter.

Anyway, thank you for your help.

---

<div class="post-metadata">

### Author: ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)
#### Post date: [25 October 2024 07:14 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/6 "2024-10-25T07:14:46Z")

</div>

> [@no\_mpimpi](#):
>
> If you have second, could you please clarify why you'd use **const** instead of **var**? Assume a strong level of ignorance on my part.

let me [google](https://letmegooglethat.com/?q=const+let+var+usage+javascript) that for you, as i do not have a great deal of time this morning.

---

<div class="post-metadata">

### Author: ![no\_mpimpi](https://avatars.discourse-cdn.com/v4/letter/n/f14d63/32.png) [@no\_mpimpi](https://discourse.nodered.org/u/no_mpimpi)
#### Post date: [25 October 2024 07:57 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/7 "2024-10-25T07:57:37Z")

</div>

😆

Fair enough. Do you know what's gross about that website, though? It has a skin that looks like Google, but the results are all Bing.

For anyone that comes here via search, my current understanding is that **const** is for variables that shouldn't change or be re-declared. The elements inside a **const** can change, but the variable itself can't.

If I've got this right, that would make **const** a far better thing for a global variable, especially in the context I'm trying to use it.

I thank you.

---

<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: [8 November 2024 07:58 UTC](https://discourse.nodered.org/t/please-help-i-have-created-a-global-variable-monstrosity-that-destroys-vms/92617/8 "2024-11-08T07:58:12Z")

</div>

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