Increment Number

Overview

Increment Number safely increments numeric values in persistent storage, ensuring atomic operations to prevent race conditions during concurrent access. This stage is designed specifically for counters and numeric values that need reliable, concurrent updates.

Use this stage when you need to maintain running counters, track totals across multiple flow executions, or implement any numeric aggregation where concurrent access is possible.

* Example flow demonstrating how Increment Number maintains a persistent spin counter for each player and immediately uses the updated value to determine whether the player has completed more than 100 spins.

Note: The variable names, values, criteria, and configuration used in this example are for demonstration purposes only.

Where to find it: Actions > Local Storage in the stage library.

Configuration

Required Fields

FieldDescriptionExample
Group nameThe organizational namespace for your counter datacounters, orderSequence
Key (Name)The identifier for the counter to incrementorderCount, totalRevenue
Value to IncrementThe amount to add to the counter (can be positive or negative). The value is always treated as a number; there is no decimal formatter, so a fractional result may display differently than you expect1, {{itemPrice}}, -5

Optional Fields

  • Record name: A sub-grouping within the group name for hierarchical organization (e.g., date-based records)
  • Time to live (minutes): How long to keep the counter before automatic deletion. Use @forever for permanent counters, @1_hour (60 min), @24_hours (1440 min), or a specific number of minutes. Note: entering 0 or a negative number means immediate expiry, NOT forever (this differs from Save Data). Use @forever or leave it empty to keep the counter indefinitely.

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

ExitWhen
PassAll counters successfully incremented and stored
ErrorA database error (timeout, connection failure, or a rejected write) routes to the Error exit

Detecting a non-change: a call that succeeds but leaves the counter value unchanged still routes to Pass, not Error. If you need to confirm the value actually changed, follow this stage with a Fetch Data stage and check the value.

How It Works

When executed, the stage:

  1. Resolves variables - Evaluates all field values including the increment amount
  2. Performs atomic increment - Uses a read-modify-write operation that prevents race conditions
  3. Creates if needed - If the counter doesn't exist, creates it with the increment value as initial value
  4. Updates dictionary - Adds the NEW counter value to flow variables for immediate use
  5. Resets TTL - Extends the counter's lifetime by the specified TTL value

Common Use Cases

1. Order Counter

Track the total number of orders processed.

  • Group name: counters
  • Key: totalOrders
  • Increment By: 1
  • Time to live: @forever

2. Daily API Call Tracking

Count API calls per day with automatic expiration.

  • Group name: apiTracking
  • Record name: {{currentDate}}
  • Key: callCount
  • Increment By: 1
  • Time to live: @24_hours

3. Revenue Aggregation

Sum total revenue from multiple transactions.

  • Group name: financials
  • Keys:
    • totalRevenue - Increment by {{orderTotal}}
    • transactionCount - Increment by 1
  • Time to live: @forever

4. Inventory Decrement

Reduce stock levels when items are purchased.

  • Group name: inventory
  • Record name: {{productId}}
  • Key: stockCount
  • Increment By: -{{quantityPurchased}} (negative value decrements)
  • Time to live: @forever

5. Rate Limiting

Track API calls per user to enforce limits.

  • Group name: rateLimits
  • Record name: {{userId}}
  • Key: callsThisHour
  • Increment By: 1
  • Time to live: 60 (1 hour)

Key Behaviors

FeatureBehavior
Atomic Operations✓ Each counter increment is atomic - safe for concurrent access
Auto-Creation✓ Counter created automatically if it doesn't exist
Negative Increments✓ Use negative values to decrement counters
Multiple Keys✓ Update multiple counters in one stage
Dictionary Update✓ New values immediately available in flow variables
TTL Reset✓ Each increment resets the expiration timer
Cross-Key Transactions✗ Multiple keys incremented independently (not atomic together)

Why Use Increment Number vs Save Data

ScenarioIncrement NumberSave Data
Concurrent updates✓ Safe - atomic operation✗ Race conditions - lost updates
Running counters✓ Designed for this✗ Manual fetch + save = risk
Non-numeric data✗ Numbers only✓ Any data type
Single flow updates✓ Works but overkill✓ Simpler for this case

Key rule: If multiple flows might update the same value simultaneously, use Increment Number. Otherwise, Save Data is simpler.

Accessing Incremented Values

After the stage executes, each incremented counter is automatically added to your flow variables with its NEW value:

Example:

  • Counter orderCount was 10
  • You increment by 5
  • {{orderCount}} now contains 15
  • Use immediately in next stages without fetching

Best Practices

  • ✓ Use Increment Number (not Save Data) whenever multiple flows might update the same counter
  • ✓ Use descriptive group and key names like orderCounts.dailyTotal
  • ✓ Set @forever for permanent counters, time-based TTLs for temporary tracking
  • ✓ Use negative values to decrement instead of fetching and subtracting
  • ✓ Update multiple related counters in one stage to save round trips
  • ✓ Connect the Error exit to handle storage failures with retry logic
  • ✓ Document your counter schema (groups, keys, purposes)

Common Mistakes

MistakeSymptomFix
Using Save Data for countersCounter values inconsistent, some increments lostSwitch to Increment Number for concurrent-safe updates
Forgetting TTL for temporary dataCounters persist indefinitely, bloat storageSet appropriate TTL for rate limits, daily counts, session data
Using inconsistent key namesData scattered across similar-sounding keysStandardize naming conventions and document them
Not handling Error exitFlow fails silently when storage unavailableConnect Error exit to retry logic or alerting
Incrementing by string instead of numberUnexpected behavior or errorsEnsure increment value is numeric or numeric variable
Mixing Save Data and Increment on same keyCounters overwritten unexpectedlyChoose one approach per key - either always Save or always Increment

Troubleshooting

IssueExit/ResultCommon CauseFix
Counter values inconsistentPass (but wrong values)Using Save Data in concurrent scenario instead of Increment NumberSwitch to Increment Number for atomic updates
Counters never expirePass (but data persists)TTL not set or set to @foreverSet appropriate TTL for temporary counters
Error exit triggeredErrorStorage system unavailable or connection failedImplement retry logic; check storage system status
Counter starts at wrong valuePass (but unexpected initial value)First increment initializes with increment value, not zeroExplicitly save initial value of 0 before first increment if needed
Multiple counters out of syncPass (but inconsistent)Each key incremented independently, not atomically togetherUse single composite key if atomicity needed across values

Edge Cases

  • Counter Doesn't Exist: First increment creates the counter with the increment value as initial value (not zero).
  • Zero Increment: Incrementing by 0 doesn't change the value but does reset the TTL.
  • Decimal Increments: Supports fractional values like 2.5 for tracking hours or partial quantities.
  • Partial Failures: If incrementing 5 keys and key #3 fails, keys #1 and #2 remain incremented (no rollback).
  • Frequently Incremented Counters: If you increment a counter with a 1-hour TTL every 10 minutes, it never expires (TTL resets on each increment).

Related Stages

  • Save Data: Store non-numeric data or when atomic increment not needed
  • Fetch Data: Retrieve current counter values for decision-making
  • Delete Data: Remove counters from storage
  • Change Data: Set counter values in flow variables (not persistent storage)
  • Route Flow: Make decisions based on counter values (e.g., rate limiting)