Persist Node-RED flow state with local filesystem context
Use Node-RED built-in localfilesystem context to keep flow and global variables across redeploys without an external database.
23 Oct 2025, 02:43 UTC

Keep Node-RED state across redeploys without an external database
Problem: a Function node increments a counter, but after you click Deploy or restart Node-RED, the counter resets to zero. Useful takeaway: enable Node-RED’s built-in localfilesystem context storage in settings.js, then read and write flow or global variables with flow.get(), flow.set(), global.get(), and global.set(). Values survive redeploys and restarts, and you do not need a database just to remember a counter, flag, or last-seen timestamp.
Context is Node-RED’s built-in key-value store. Flow context is scoped to one tab (flow); global context is shared across all tabs in the same Node-RED instance. Node-RED 1.x and later default to localfilesystem persistence, while versions before 1.0 kept context in memory only and lost it on restart unless you configured an external store.
Configure localfilesystem context storage
Open settings.js in your Node-RED user directory. On Linux and macOS this is commonly ~/.node-red/settings.js; on Windows it is typically under %APPDATA%\node-red. You need write permission for the user account that runs the Node-RED process.
Add or edit the contextStorage block so the default module is localfilesystem:
contextStorage: {
default: {
module: 'localfilesystem'
}
}
Save the file and restart Node-RED, not just redeploy the flow. A redeploy reloads flows but does not always re-read settings.js.
Read and write context in a Function node
This Function node increments a flow-scoped counter and returns the current value:
let count = flow.get('counter') || 0;
count += 1;
flow.set('counter', count);
return { payload: count };
Use global.get('key') and global.set('key', value) the same way for instance-wide state. The string 'counter' is the key; you can choose any key name that fits your flow.
Verify that persistence works
- Restart Node-RED after saving settings.js.
- Open the editor, place the Function node above in a flow, and deploy.
- Inject a message into the Function node a few times and watch the payload increase.
- Click Deploy to redeploy the flow, then inject again. The counter should continue from its previous value instead of starting at zero.
- In the editor, open the context sidebar and select Flow or Global to inspect stored keys and values.
- On the filesystem, expect a context/ folder under your Node-RED user data directory containing per-flow and global JSON files.
If the counter resets after redeploy, confirm that contextStorage.default.module is set to localfilesystem and that you restarted the runtime, not only redeployed the flow.
Limits and common mistakes
Values must be JSON-serializable
Context is serialized to JSON. Functions, undefined, symbols, and circular references are silently dropped. Do not store streams, buffers, or class instances. Plain objects, arrays, strings, numbers, and booleans are safe.
Context is per-process, not shared instantly
File-based context belongs to the running Node-RED process. If you run two instances against the same context folder, they do not synchronize writes. The last instance to write a key wins, which can overwrite changes from the other instance. Do not use context as a shared state store across multiple runtimes.
In-place object mutation is not persisted
If you retrieve an object, change a property, and do not call flow.set() again, the change is lost on restart:
let config = flow.get('settings') || {};
config.theme = 'dark'; // changed in memory only
// Missing: flow.set('settings', config);
Always write the object back after mutation.
Stale state survives redeploys
Because context persists across redeploys, old counters, flags, or cached values can cause unexpected behavior after you change a flow. Treat context as long-lived state, not temporary scratchpad memory.
Rollback
To disable persistence, remove the contextStorage block from settings.js or change the module back to memory, then restart Node-RED. Existing context files remain on disk until you delete them, so old keys may still appear in the context sidebar until the files are removed.
Practical check
Run one Node-RED instance, write a known value to a flow key, restart the runtime, and read the key again in a new Function node. If the value returns, persistence is working. To test the concurrency limit, start two instances with the same context path, write different values to the same key from each, and observe which value survives; expect last-write-wins behavior.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.