Hello! Welcome back to our module on "Modular and Reusable Workflows."
In our last lesson, we focused on making your logic reusable by creating sub-workflows. You learned how to encapsulate a set of actions into a callable module, which is a core principle for building clean and maintainable automations. This is analogous to writing a function in a programming language.
Today, we're going to tackle the other side of the reusability coin: making your data and configuration reusable within a workflow. Imagine you have a workflow that makes several API calls to the same service. Hardcoding the base URL or an API version in each node would violate the DRY ("Don't Repeat Yourself") principle you're familiar with from software development. If that URL changes, you'd have to update it in multiple places.
This lesson will introduce a powerful feature for managing this kind of shared data. By the end, you will be able to use workflow static data for shareable configuration.
1. Methods for Managing Configuration
In n8n, there are several ways to manage configuration values like URLs, IDs, or other settings. Let's compare the main options to understand where "workflow static data" fits.
- Hardcoding: Typing a value directly into a node's parameter field. It's simple for one-off uses but poor practice for values used in multiple places.
- Credentials: The secure, encrypted way to store secrets like API keys, usernames, and passwords. You've already used these for connecting to services.
- Environment Variables: These are variables set at the level of your n8n instance, often in a Docker configuration file. They are available to all workflows on that instance and persist until the instance is reconfigured. They are ideal for global settings that rarely change, like a master API key or the domain name of your application. Your software development background makes you very familiar with this concept.
To see how environment variables work in n8n, you can watch this quick video.
n8n Environment Variables: What They Are and How to Use Them
This video, 'n8n Environment Variables' from Leonardo Grigorio, demonstrates how to set and use instance-level environment variables. This will help you distinguish them from the workflow-specific data we're about to cover.
Watch the sections from 00:00 to 01:15 and 02:59 to 03:50. Focus on what an environment variable is and how it's accessed (using the $env object) across different nodes.
- Workflow Static Data: This is our focus today. It's a temporary, in-memory key-value store that exists only for the duration of a single workflow execution. It's the perfect tool for:
- Defining configuration that is specific to one run.
- Passing data between nodes that are not directly connected, for example, across different branches.
- Maintaining state during complex operations like loops.
2. Understanding Workflow Static Data
Workflow static data is accessed and manipulated using a built-in function, primarily within the Code node or expressions. The official n8n documentation provides the technical details.
getWorkflowStaticData | n8n Docs
The official n8n documentation for getWorkflowStaticData is the definitive source for this feature. It explains the function and the two types of static data.
Read the introductory section down to 'Example with global data'. Pay close attention to the distinction between 'global' and 'node' static data.
As the documentation states, there are two types:
- Global Static Data (
global): This is the most common type. Data stored here is accessible from any node within the same workflow execution. This is what we'll use for shareable configuration. - Node Static Data (
node): This data is unique to the specific node that set it. It's useful for a node to remember its own state across multiple executions, which can happen in loops or with certain trigger setups.
You can think of global static data as a temporary global variable scoped to a single run of your workflow.
3. Hands-On: Centralizing Workflow Configuration
Let's build a simple workflow to see this in action. We'll create a workflow that fetches a user and their posts from a public API, defining the API's base URL once in static data.
1. Create a New Workflow:
- Start with a Manual trigger.
2. Initialize Configuration:
- Add a Code node and connect it to the trigger.
- This node's purpose is to set up our shared configuration. Paste the following JavaScript code into it:
// Get the global static data object const config = $getWorkflowStaticData('global'); // Set configuration properties on the object config.apiBaseUrl = "https://jsonplaceholder.typicode.com"; config.userId = 1; // This node doesn't need to return data, // its job is to modify the static data. // We'll return a simple status message. return [{ json: { status: "Config initialized" } }]; - This code gets the
globaldata store and adds two properties to it:apiBaseUrlanduserId.
3. Fetch User Data:
- Add an HTTP Request node and connect it to the Code node.
- In the URL field, use an expression to construct the URL from our static data:
{{ $getWorkflowStaticData('global').apiBaseUrl }}/users/{{ $getWorkflowStaticData('global').userId }}
4. Fetch Post Data:
- Add a second HTTP Request node, also connected to the initial Code node (creating a parallel branch).
- In its URL field, use a similar expression to get the posts for that user:
{{ $getWorkflowStaticData('global').apiBaseUrl }}/posts?userId={{ $getWorkflowStaticData('global').userId }}
5. Execute and Inspect:
- Execute the workflow.
- You'll see that both HTTP Request nodes ran successfully. Inspect their inputs/outputs. They both used the
apiBaseUrlanduserIddefined in a single, central place. If you needed to change the user ID or switch to a different API environment, you would only need to edit the Code node.

4. Advanced Use Case: Managing State in Batch Operations
Beyond simple configuration, workflowStaticData is essential for managing state in more complex scenarios. Its ability to act as a temporary data store is critical when you're processing data in batches or loops.
A fantastic, real-world example is performing a data sync between two systems. The following blog post explains how to use workflowStaticData to keep track of which records need to be created and which need to be updated while processing a large dataset in batches.
How to sync batched data with workflowStaticData in n8n ...
This blog post by Juliet Edjere provides an excellent real-world example of using workflow static data to manage state during a complex data synchronization task. It goes beyond simple configuration and shows how to use it as a temporary data store within a single workflow execution.
First, read 'Key characteristics of workflowStaticData'. Then, carefully review the code and explanations for 'Step 2: Build a Lookup Map and initialize state' and 'Step 5: Process batches & track state'. Finally, read 'Best practices for using workflowStaticData'. Focus on how workflowStaticData is used to initialize lists and then accumulate data across multiple batches.
The key pattern from the article is a powerful one for any developer to know:
- Initialize: At the start of the workflow, a Code node is used to initialize the static data, often creating empty arrays or objects (e.g.,
workflowStaticData.itemsToCreate = []). - Accumulate: Inside a loop (e.g., after a
Split In Batchesnode), another Code node runs for each batch. It retrieves the current arrays from static data, adds items to them, and—crucially—saves the modified arrays back to the static data object. - Consume: After the loop completes, downstream nodes can access the final, fully populated arrays from static data to perform batch operations.
Test your understanding!
In the pattern described above, why is the last step in the "Accumulate" phase ("saves the modified arrays back") so important? Imagine the code inside your Split in Batches loop looks like this:
let createList = $getWorkflowStaticData('global').batch_create_list;
createList.push({ name: 'new item' });
// ... is something missing?
What would happen on the next iteration of the loop?
Show answer
On the next iteration, $getWorkflowStaticData('global').batch_create_list would still refer to the original, unmodified list from before the current iteration started. The changes made to the local createList variable are not automatically persisted back to the global static data store.
The loop would effectively "forget" the items it added in the previous iteration. The crucial missing line is:$getWorkflowStaticData('global').batch_create_list = createList;
This re-assigns the modified local array back to the static data store, ensuring the state is correctly accumulated across all batches.
Conclusion
You've now added another essential tool for building robust and maintainable workflows. By centralizing configuration and managing state with workflowStaticData, you can create automations that are easier to read, debug, and update.
Key Takeaways:
- Workflow Static Data is a key-value store that persists for a single workflow execution, perfect for run-specific configuration or state.
- It is distinct from Environment Variables, which are global to the n8n instance and persist across all executions.
- Use a Code node to initialize your configuration at the start of a workflow by setting properties on the
$getWorkflowStaticData('global')object. - Access these values in any subsequent node using an expression like
{{ $getWorkflowStaticData('global').myValue }}. - For advanced patterns like accumulation in loops, remember to retrieve the data, modify your local copy, and then re-assign it back to the static data object to persist the changes for the next iteration.
Preview of the Next Lesson:
We've made our workflows modular and configurable. But what happens if a trigger fires twice with the same data? You might create two duplicate records or send the same email twice. In our next lesson, we will learn how to build idempotent workflows to safely handle duplicate trigger events, ensuring your automations can be run multiple times without causing unintended side effects.