n8n Workflow Static Data Not Saved on Manual Execution: Why It Resets and What to Use
n8n static data is not saved during manual or test runs, only for published workflows triggered normally. How I designed around it and what the docs recommend.
If a value you store with $getWorkflowStaticData() is gone the next time you click Execute workflow, nothing is broken. According to the n8n documentation, static data is not available when testing a workflow. It is saved only when the workflow is published and called by its trigger or a webhook. This guide explains how I ran into it and how I designed around it.
The short answer
- Manual and test executions do not save static data. Production executions of a published workflow do.
- Static data is saved when an execution succeeds. n8n checks for changes and saves them if necessary.
- It works only in the JavaScript Code node, not in the Python one.
- It is marked as experimental. The documentation says the data should be small and that it may behave unreliably under high-frequency executions.
All four points come from the n8n static data documentation.
How it showed up in my workflow
I run a small workflow, on n8n 2.8.3 self-hosted, that reads my WordPress post sitemap every 15 minutes and sends me a Telegram message and an email when a new post URL appears. To avoid sending the same post twice, it keeps the list of URLs it has already seen in global static data.
Because manual runs do not save static data, a list stored this way cannot be tested by clicking Execute workflow repeatedly. I made two choices because of that.
- The first scheduled run only records the posts that already exist and sends nothing, so a fresh start does not flood me with alerts for every old post.
- I added a
testModesetting. When it is on, the workflow ignores the saved list and treats the most recent URL as new, so I can check the Telegram and email steps without publishing a post. I turn it off before publishing the workflow.
After I published the workflow, a Telegram alert for a newly published post arrived, which is what I wanted to see.
A minimal check, and what I observed
To see the difference myself, I built a two-node workflow: a Schedule Trigger set to run every minute, followed by a JavaScript Code node that counts its own runs in global static data.
const sd = $getWorkflowStaticData('global');
sd.runs = (sd.runs || 0) + 1;
sd.lastRun = new Date().toISOString();
return [{ json: { runs: sd.runs, lastRun: sd.lastRun, mode: String($execution && $execution.mode) } }];- I clicked Execute workflow three times.
- I published the workflow and let the schedule run.
- I opened the Executions list and read the output of the Code node for individual runs.
This is what the node returned on 2026-10-19 on n8n 2.8.3, self-hosted.
| Run | mode | runs |
|---|---|---|
| Manual run (the third of three) | test | 1 |
| First scheduled run after publishing | production | 1 |
| Second scheduled run | production | 2 |
| Third scheduled run | production | 3 |
- The third manual run still returned
runs1. If the earlier manual runs had been saved, it would have been 3. - The first scheduled run also started at 1, so the manual runs did not carry over into the published workflow.
- The second and third scheduled runs returned 2 and 3, so the value was kept between runs of the published workflow.
$execution.modereturnedtestfor the manual run andproductionfor scheduled runs, which is a handy way to see which kind of run you are looking at.
This matches what the documentation says. Note what I recorded: I read the outputs of the third manual run and of the first three scheduled runs. I did not write down the outputs of the first two manual runs or of later scheduled runs.
What to use instead
The documentation recommends data tables for keeping data between executions. It says they work in test executions and do not require a Code node: you read a value with the Data Table node's Get row operation and write it with Upsert row. I did not use data tables in this workflow, so I cannot tell you how they behave beyond what the documentation says.
What I did not test
- I tested only a one-minute schedule and looked at three scheduled runs, so I cannot say anything about long-running or high-frequency workflows.
- I did not test data tables.
- I did not test queue mode or multiple workers.
- I tested nothing on versions other than 2.8.3, and the documentation wording may change between versions.
Source: n8n documentation, static data in workflows. I read it on 2026-10-19 and ran the check described above on the same day.
Updated: Oct 19, 2026