Flow Studio
Pinned Data
Pinned data is durable, per-node output that persists across multiple execution runs. Unlike ephemeral node output — which lives only for the duration of a single execution — pinned data is stored in the database and is readable by the same node or any downstream node in future executions.
Ephemeral vs. Pinned
| Attribute | Ephemeral Output | Pinned Data |
|---|---|---|
| Lifetime | Single execution run | Persists across runs until explicitly cleared |
| Storage | In-memory (executionStore.nodeOutputs) | Database (Process_NodePinnedData table) |
| Scope | (executionId, nodeId) | (processId, nodeId) — shared across all runs of the same workflow |
| How to set | First arg of NodeExecutionResult.Success(output) | Second arg of NodeExecutionResult.Success(output, pinnedData) |
| How to read | ctx.ExecutionMemory.GetNodeOutput<T>(nodeId) | ctx.ExecutionMemory.GetPinnedData(nodeId) |
| Visible in Node Inspector | Output Data section | Pinned Data section (collapsible, only if non-null) |
When to Use Pinned Data
Use pinned data when a node produces output that should survive between runs and be accessible to future executions of the same workflow.
| Scenario | Use Pinned Data? |
|---|---|
| Fetch and pass a value to the next node in this run | No — ephemeral output is sufficient |
| Cache an API response to avoid re-fetching in future runs | Yes |
| Store AI agent conversation history across workflow triggers | Yes |
| Accumulate a running total that persists across invocations | Yes |
| Intermediate calculation used only within one run | No — ephemeral output is sufficient |
How Pinned Data Flows
Executor calls
NodeExecutionResult.Success(output, pinnedData)→
BaseNodeExecutor detects non-null pinnedData and calls
PinnedDataService.SaveAsync(processId, nodeId, pinnedData)→
Saved to
Process_NodePinnedData table (upsert by processId + nodeId)→
Node Inspector fetches pinned data from API and displays in Pinned Data section
Guide Contents
| Page | What You Will Learn |
|---|---|
| Returning Pinned Data | The NodeExecutionResult.Success(output, pinnedData) overload and the PinnedDataObject type |
| Pinned Data Storage | Process_NodePinnedData table schema and upsert behavior |
| Reading Pinned Data | ctx.ExecutionMemory.GetPinnedData(nodeId) — cross-run access pattern |
| Node Inspector Display | How the PinnedData section renders in the Observer Panel |
| Clearing Pinned Data | Explicit clear, TTL expiry, and node-removal cascade |
| Use Cases | AI memory, accumulation, caching patterns |
| Security Considerations | Tenant isolation, PII guidance, encryption at rest |
Pinned data is NOT part of
ExecutionMemory.nodeOutputs. The ephemeral output store and the pinned data store are completely separate systems. Reading a node's pinned data uses a distinct API call (GetPinnedData), not the same lookup as ephemeral outputs (GetNodeOutput).