Fetch Data
Overview
Fetch Data retrieves previously stored data from persistent storage that was saved using the Save Data stage. Use this stage to load user sessions, cached API responses, configuration settings, or any data saved earlier in your flows.
* Example flow demonstrating how Save Data stores player information and how Fetch Data retrieves the stored values using the player's {{userId}}. If a requested key is not found, the configured default value is used instead.
Note: The variable names, values, criteria, and configuration used in this example are for demonstration purposes only.
Configuration
Required Fields
| Field | Description | Example |
|---|---|---|
| Group name | The organizational namespace where your data is stored (must match group name from Save Data) | userSessions, orderCache |
| Key (Name) | The identifier of the data to retrieve (must match key used when saving) | userId, lastOrderDate |
| Default value | The value to return if the key is not found (prevents errors when data doesn't exist) | not_found, 0, {} |
Optional Fields
- Record name: The sub-grouping within the group name. If data was saved with a record name, you must provide it to retrieve. If omitted, fetches from the default record.
Using functions in these fields: Any value field above accepts @ functions, for example @NowSecond for the current time or @calc(...) for a calculation.
See Flows Functions for the full list.
Exit Points
| Exit | When |
|---|---|
| Pass | Data successfully retrieved (or defaults used for missing keys) |
| Error | Database connection failure or exception occurred during fetch |
Important: This stage does NOT have a Fail exit. Missing data uses default values and routes to Pass.
How It Works
When executed, the stage:
- Resolves configuration - Evaluates group name, record name, and key names from variables
- Checks cache - If caching enabled, checks for cached values first (skips database if all keys found)
- Fetches from database - Retrieves all data for the group+record combination in a single query
- Loads into variables - Extracts requested keys and makes them available as flow variables (uses defaults for missing keys)
Accessing Retrieved Data
After the stage executes, each fetched key becomes available as a flow variable:
Example:
- Fetch key named
email - Use it as
{{email}}in subsequent stages - No prefix needed - use the key name directly
Common Use Cases
1. Retrieve User Session
Load user session data saved at login.
- Group name:
userSessions - Record name:
{{userId}} - Keys:
loginTime- Default:not_foundipAddress- Default:unknownuserEmail- Default:no_email
2. Load Cached API Data
Retrieve cached API response to avoid external call.
- Group name:
apiCache - Record name:
productData - Keys:
products- Default:[](empty array)fetchedAt- Default:never
3. Restore Multi-Step Form
Load partial form data when user returns to complete submission.
- Group name:
formSubmissions - Record name:
{{sessionId}} - Keys:
step1_personalInfo- Default:{}step2_address- Default:{}status- Default:new
4. Check Counter Value
Retrieve current counter to determine if limit reached.
- Group name:
counters - Keys:
orderCount- Default:0lastUpdated- Default:never
Key Behaviors
| Feature | Behavior |
|---|---|
| No Fail Exit | Missing data does NOT trigger Fail - uses defaults and routes to Pass |
| Default Values | ✓ Always provide defaults - used when data not found or expired |
| Multiple Keys | ✓ Fetch multiple keys in one stage (single database query) |
| Partial Retrieval | ✓ If fetching 5 keys and only 3 exist, found keys get values, missing get defaults |
| Caching Support | ✓ Prefix group name with cache(60):: for caching (60 = seconds) |
| Variable Names | ✓ Use key name directly as variable (e.g., key email → {{email}}) |
Cache Optimization
Prefix the group name with cache(ttl):: to enable caching:
Example: cache(60)::userSessions
This will:
- Check local cache before querying database
- If ALL requested keys found in cache, skip database query entirely
- If ANY key missing from cache, fetch ALL from database and update cache
- Cache expires after specified TTL (in seconds)
Detecting Missing Data
Since there's no Fail exit, use Route Flow to detect if data was actually found:
Example:
- Fetch key
emailwith defaultnot_found - Use Route Flow to check:
{{email}}equalsnot_found - If true, data doesn't exist; if false, data was found
Best Practices
- ✓ Always provide meaningful defaults (not just empty strings)
- ✓ Match group/record/key names exactly with your Save Data stage
- ✓ Fetch all related keys together (single database query is more efficient)
- ✓ Use Route Flow after Fetch to compare against defaults and detect if data was found
- ✓ Connect Error exit to handle database connection failures
- ✓ Use descriptive key names that make it clear what data is being fetched
- ✓ Document your storage schema (which groups, records, and keys are used where)
- ✓ Consider TTL expiration timing - expired data treated as missing
Common Mistakes
| Mistake | Symptom | Fix |
|---|---|---|
| Mismatched group/record names | Default values used instead of saved data | Ensure exact name match with Save Data stage (case-sensitive) |
| Forgetting default values | Stage configuration incomplete | Always provide a sensible default for each key |
| Expecting a Fail exit | Flow logic doesn't handle missing data properly | This stage only has Pass and Error - use Route Flow to detect missing data |
| Using wrong record name | Fetching from wrong user's data | Double-check record name matches (e.g., {{userId}}, not {{userName}}) |
| Variable name confusion | Can't access fetched data | Use key name directly as variable: {{email}} not {{fetchData.email}} |
| Assuming data format | Unexpected data type or structure | No automatic JSON parsing - data returned as stored; validate type after fetching |
Troubleshooting
| Issue | Exit/Result | Common Cause | Fix |
|---|---|---|---|
| Default values used instead of saved data | Pass (but wrong values) | Case mismatch in group/record/key names, or data expired | Verify exact names match Save Data; check TTL hasn't expired |
| Error exit triggered | Error | Database connection failure or invalid data store ID | Check database connectivity; verify data store configuration |
| Some keys work, others don't | Pass (partial data) | Some keys exist, others don't (or expired) | This is normal behavior - missing keys use defaults; check Save Data saved all keys |
| Can't access fetched variable | Pass (but variable undefined) | Using wrong variable syntax or name | Use {{keyName}} directly, not {{fetchData.keyName}} |
| Stale data returned | Pass (but old data) | Caching enabled with long TTL, or data not updated | Check cache TTL; verify Save Data is actually updating the values |
Edge Cases
- Partial Data Retrieval: If fetching 5 keys and only 3 exist, the 3 found keys get database values and 2 missing keys get default values. Stage routes to Pass (not Error).
- Expired Data: Expired keys treated as "never existed" - default value used. No way to distinguish "expired" from "never saved".
- Empty Group/Record: Non-existent group or record returns empty data - all keys use defaults and stage routes to Pass.
- Caching All-or-Nothing: If ANY requested key missing from cache, fetches ALL from database (no partial cache hits).
- No Multi-Record Fetch: One fetch operation retrieves from one group+record combination. To fetch from multiple records, use multiple Fetch Data stages or Loop.
Related Stages
- Save Data: Store data that this stage retrieves
- Delete Data: Remove stored data when no longer needed
- Increment Number: Safely update numeric values in storage
- Query Data: Search stored data based on conditions
- Route Flow: Make decisions based on fetched values (compare against defaults)
- Change Data: Process or validate fetched values before using them