# A guide to understanding 'Persistent Context'

**URL:** <https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115>\
**Category:** General\
**Created:** [19 October 2018 10:13 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115 "2018-10-19T10:13:24Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [20 October 2018 07:18 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/22 "2018-10-20T07:18:27Z")

</div>

Don’t forget, the current implementation only gets flushed to disk every 30secs. It is there if you “get” it immediately( from the cache) but may not be in the file.

---

<div class="post-metadata">

**Author:** ![rsuplido](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rsuplido/32/3210_2.png) [@rsuplido](https://discourse.nodered.org/u/rsuplido)\
**Post date:** [20 October 2018 13:19 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/23 "2018-10-20T13:19:36Z")

</div>

@RogierQ, Here's a test I made:

> ```
> contextStorage: {
> store: {
> module:"localfilesystem"
> },
> default: {
> module:"memory"
> }
> },
> 
> ```

Here's how my test flow looks:

 ![persistent_context](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/4/46ba12a60afeebef8ade7d3779d1e491934441a2.png)

Here's the code:

```auto
[{"id":"1b12c10.509463f","type":"tab","label":"Persistent Context Test","disabled":false,"info":""},{"id":"73e93758.9aa008","type":"inject","z":"1b12c10.509463f","name":"","topic":"","payload":"B","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":140,"wires":[["532bf815.546508"]]},{"id":"7d06f012.51671","type":"inject","z":"1b12c10.509463f","name":"","topic":"","payload":"A","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":100,"wires":[["532bf815.546508"]]},{"id":"5d36a28e.6f402c","type":"inject","z":"1b12c10.509463f","name":"","topic":"","payload":"C","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":180,"wires":[["532bf815.546508"]]},{"id":"532bf815.546508","type":"function","z":"1b12c10.509463f","name":"Set context","func":"flow.set(\"cxTest\", msg.payload, \"store\");\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":140,"wires":[["4fb35e5c.8cb35"]]},{"id":"4fb35e5c.8cb35","type":"debug","z":"1b12c10.509463f","name":"Set value","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":660,"y":140,"wires":[]},{"id":"667f1611.ddc8a8","type":"inject","z":"1b12c10.509463f","name":"Show stored context","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":240,"wires":[["fce453bf.1b35a"]]},{"id":"fce453bf.1b35a","type":"function","z":"1b12c10.509463f","name":"Get context","func":"msg.payload = flow.get(\"cxTest\",\"store\") || \"empty\";\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":240,"wires":[["5663ce9f.ca75b"]]},{"id":"5663ce9f.ca75b","type":"debug","z":"1b12c10.509463f","name":"Get value","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":660,"y":240,"wires":[]},{"id":"cecdc7e2.8718e8","type":"inject","z":"1b12c10.509463f","name":"Get stored context at deploy/startup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":220,"y":280,"wires":[["fce453bf.1b35a"]]}]

```

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [20 October 2018 14:22 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/24 "2018-10-20T14:22:31Z")

</div>

(did you start and end the flow with three backtic's on the line before and after it? I could not import it)

And??? I had to fudge to get your flow to import, but it is working for me. Are you saying that you have an issue? If so what is it?

---

<div class="post-metadata">

**Author:** ![rsuplido](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rsuplido/32/3210_2.png) [@rsuplido](https://discourse.nodered.org/u/rsuplido)\
**Post date:** [20 October 2018 14:36 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/25 "2018-10-20T14:36:02Z")

</div>

@zenofmud, sorry, I was replying to @RogierQ to help show a test flow. Fixed the code as well. Thanks.

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [20 October 2018 14:44 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/26 "2018-10-20T14:44:59Z")

</div>

> [@knolleary](#):
>
> @krambriw _any_ sort of persistent storage needs to write to the SD card, unless you use some external storage mechanism (USB hard drive, cloud storage api...). It's hard to get around that.
> 
> To help minimise the wear, the default mode for the file persistence is to batch up writes to the card every 30 seconds. This does mean if Node-RED crashes unexpectedly, you may not have up to the last 30 seconds worth of data stored. That's the trade-off between writing every update to disk as it happens and trying to minimise wear.

Is this configurable? There's no denying that this is essential behavior on SD but there are bound to be folks running NR on way bigger hardware. (For example 4 of my deployments are in ESX clusters with flash based SAN storage...)

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [20 October 2018 15:00 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/27 "2018-10-20T15:00:03Z")

</div>

> [@JayDickson](#):
>
> Is this configurable?

Yes, that's why I said it was the default mode.

The documentation describes the various configuration options for the file store.

[https://nodered.org/docs/api/context/store/localfilesystem](https://nodered.org/docs/api/context/store/localfilesystem)

---

<div class="post-metadata">

**Author:** ![rsuplido](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rsuplido/32/3210_2.png) [@rsuplido](https://discourse.nodered.org/u/rsuplido)\
**Post date:** [20 October 2018 15:30 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/28 "2018-10-20T15:30:40Z")

</div>

@knolleary can you explain further why the cache is set to true by default? Don't you think it should be false by default since it gives you more control to store the current value only on 'set'? Or is the intention/use case is to define the context as persistent (e.g. flow.set("temperature", "33", "storeInFile"); ), keep assigning values to the context by regular assignment (e.g. flow.temperature = "38"), and then auto save to file every flushInterval?

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [20 October 2018 16:07 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/29 "2018-10-20T16:07:59Z")

</div>

@rsuplido the main reason to enable the cache by default is that is allows _all_ existing flows to continue to work without any changes.

If you disable the cache, then every context get or set needs to access the file on disk. This can only be done asynchronously. So existing synchronous code will not work.

For example:

```auto
var temperature = flow.get("temperature");

```

will not work with the cache disabled. Instead, it needs to do:

```auto
flow.get("temperature", function(temperature) {
    // do something with temperature
});

```

This is described in the Function node docs - [https://nodered.org/docs/writing-functions#storing-data](https://nodered.org/docs/writing-functions#storing-data)

Putting disk IO in the main path will also have a performance impact. Using the cache means the main path is unaffected and the flushing to disk can happen as a background action.

Any 3rd-party node that accesses context needs to be updated to support async access - that isn't going to happen overnight and may take some time for node maintainers to take action.

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [20 October 2018 16:58 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/30 "2018-10-20T16:58:23Z")

</div>

I figured as much, but with linguistic nuance I learned to resist assumptions long ago. Thanks for the link to documentation.

---

<div class="post-metadata">

**Author:** ![RogierQ](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rogierq/32/3211_2.png) [@RogierQ](https://discourse.nodered.org/u/RogierQ)\
**Post date:** [21 October 2018 09:53 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/31 "2018-10-21T09:53:29Z")

</div>

Thanks! Got it running now. Works great 😉

Last idea / question, how can i clear all saved globals?  
Just delete the file? I gues not because it is also in the memory?

---

<div class="post-metadata">

**Author:** ![ukmoose](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ukmoose/32/13_2.png) [@ukmoose](https://discourse.nodered.org/u/ukmoose)\
**Post date:** [21 October 2018 10:16 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/32 "2018-10-21T10:16:09Z")

</div>

you can delete a specific global by using the change node. Not sure how to do a blanket “delete all”

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [21 October 2018 14:55 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/33 "2018-10-21T14:55:00Z")

</div>

> [@ukmoose](#):
>
> you can delete a specific global by using the change node. Not sure how to do a blanket “delete all”

My last big project involved pulling in and parsing data from about 500 temp/humidity sensors to build a set of watchdog timers (that part is still in the works) and an alerting/silencing system for alarms associated with those values and their optimal ranges. Some of the sensors go online/offline for days at a time (part of the problem I'm wanting to pin down) so I had to programmatically define all of my flow variables and let the flow "settle" for a bit between attempts to get the parsing algorithm right for my data.

How nice it would have been to have a quick "delete field" button when I was doing cleanup. (Made do just fine with the change node trick, though. I'm assuming my use case was not close enough to normal to warrant priority on such a feature.)

---

<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:** [21 October 2018 15:10 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/34 "2018-10-21T15:10:31Z")

</div>

> [@JayDickson](#):
>
> How nice it would have been to have a quick "delete field" button when I was doing cleanup. (Made do just fine with the change node trick, though. I'm assuming my use case was not close enough to normal to warrant priority on such a feature.)

I would also vote for a button against each variable in the context data sidebar to have as a quick delete. Really helpful when developing but also helpful when you forgot to set the correct mode and you then end up with an extra copy of the variable in more than one place but with the same name.

---

<div class="post-metadata">

**Author:** ![pelis](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pelis/32/5055_2.png) [@pelis](https://discourse.nodered.org/u/pelis)\
**Post date:** [23 October 2018 07:40 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/35 "2018-10-23T07:40:50Z")

</div>

You are saying that node id's don't change. I have been stumbling over this using subflows. It appears that once a subflow gets linked to a node, the nodes that are contained in the subflow seem to be created dynamically and such nodes will get a new node id on each deploy. That actually broke one of my implementation concepts trying to keep cache data for my nodes. That works fine unless nodes are contained in a subflow. In such case the node get’s the ‘\_alias’ member which seems to refer to it’s subflow container – unfortunately, the actual node id changes on a deploy. That’s at least what I have experienced. I have not been able to track nodes that are contained in a subflow – any hint whether that’s possible is highly appreciated.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [23 October 2018 09:06 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/36 "2018-10-23T09:06:00Z")

</div>

If you look at the [documentation](https://nodered.org/docs/user-guide/context) you will see:

> _Note_ : for nodes within a subflow, the 'flow' context is scoped to the subflow. The nodes cannot access the flow context of the flow containing the subflow instance node.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [23 October 2018 09:42 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/37 "2018-10-23T09:42:51Z")

</div>

@zenofmud that isn't quite related to the question from @pelis.

@pelis you've raised a good question. The individual instances of nodes within a subflow _may_ get different ids when they are instantiated - which will be an issue if you're trying to use node-scoped context. I don't have a quick answer for that - it's something we need to look at in the core of node-red.

---

<div class="post-metadata">

**Author:** ![pelis](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pelis/32/5055_2.png) [@pelis](https://discourse.nodered.org/u/pelis)\
**Post date:** [23 October 2018 09:47 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/38 "2018-10-23T09:47:41Z")

</div>

Thanks - that would be really helpfull

---

<div class="post-metadata">

**Author:** ![dkomando](https://avatars.discourse-cdn.com/v4/letter/d/ecd19e/32.png) [@dkomando](https://discourse.nodered.org/u/dkomando)\
**Post date:** [23 October 2018 16:12 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/39 "2018-10-23T16:12:04Z")

</div>

I think one thing that needs to be clarified in this post or even in the PR is that any data set to contextStorage will only be available to the flow or tab you are working on and not globally.

Probably should go without saying but always good to clarify.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [23 October 2018 16:23 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/40 "2018-10-23T16:23:30Z")

</div>

@dkomando one of the first sections in the docs is about the context scope - it explains the three different scopes of context available to you - [https://nodered.org/docs/user-guide/context#context-scopes](https://nodered.org/docs/user-guide/context#context-scopes)

Does that cover it for you?

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [23 October 2018 17:43 UTC](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/41 "2018-10-23T17:43:28Z")

</div>

Good point, so I changed one line to read:

> As of v.0.19.0 you can now store node, flow and global context data in memory OR in a file which will persist over restarts.

[Previous page](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115.md?page=1)

[Next page](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115.md?page=3)
