Limit Route

Overview

Limit Route controls flow execution rate by allowing execution only once per specified time window. It uses distributed locking to prevent re-execution until the time window expires, making it ideal for rate limiting, preventing duplicates, and throttling operations.

Configuration

Required Fields

FieldDescriptionExample 
Time in SecondsNumber of seconds to lock this route after execution3600 (1 hour), 300 (5 minutes)

Optional Fields

  • Limit Name: Custom identifier for this rate limit. If not provided, defaults to stage and flow ID. Use the same Limit Name across different flows to share rate limits. Can include variables for dynamic naming (e.g., email_sent_ {{user}}).

Exit Points

ExitWhenFlow Direction 
PassLimit not exceeded (first execution or after window expires)✓ Lock created, flow continues normally
FailLimit exceeded (lock exists and hasn't expired)✗ Routes to alternative handling or error path

How It Works

When executed, Limit Route:

  1. Resolves the limit name - Uses custom name if provided, otherwise defaults to stage and flow ID
  2. Checks for existing lock - Queries distributed storage for active rate limit
  3. Routes based on lock status - If lock exists, routes to Fail; if not, creates lock and routes to Pass
  4. Sets expiration automatically - Lock expires after specified seconds, allowing next execution

Rate Limiting Model: Sliding window that resets from the last successful Pass execution.

Common Use Cases

1. Prevent Duplicate Email Sends

  • Limit Name: email_sent_{{user}}
  • Time in Seconds: 3600 (1 hour)
  • Pass Path: Send Email → End
  • Fail Path: End (skip email)
  • Result: Maximum 1 email per hour per user

2. API Rate Limiting

  • Limit Name: api_call_limit
  • Time in Seconds: 6 (enforces 10 calls/minute)
  • Pass Path: Call API → Continue
  • Fail Path: Return error message
  • Result: Minimum 6 seconds between API calls

3. User Action Cooldown

  • Limit Name: reward_claimed_{{user}}
  • Time in Seconds: 86400 (24 hours)
  • Pass Path: Save reward to database
  • Fail Path: Return "Already claimed today"
  • Result: One reward claim per day per user

4. Shared Rate Limit Across Flows

  • Limit Name: notification_limit_{{user}} (same in all flows)
  • Time in Seconds: 3600
  • Flows: Order confirmations, marketing, system alerts
  • Result: All flows share same limit, coordinating automatically

5. Debouncing Rapid Triggers

  • Limit Name: file_process_{{field}}
  • Time in Seconds: 30
  • Pass Path: Process file
  • Fail Path: Ignore rapid changes
  • Result: Process file once per 30-second window, ignore rapid edits

Key Behaviors

FeatureBehavior 
Distributed Execution✓ Works across multiple servers; limit shared cluster-wide
Workspace Isolation✓ Limits scoped per workspace; different workspaces independent
Time Precision1-second precision; no sub-second timing
Window TypeSliding window; resets from last Pass execution (not fixed boundaries)
Error HandlingFail-open; if connection errors occur, routes to Pass (allows execution)
ConcurrencyRace condition possible; two simultaneous executions might both Pass

Best Practices

  • ✓ Use descriptive Limit Names that clearly indicate what's being limited
  • ✓ Include entity IDs in names for per-entity limits (e.g., {{user}})
  • ✓ Choose appropriate time windows balancing protection and user experience
  • ✓ Always handle the Fail path gracefully with clear user feedback
  • ✓ Test with actual timing to verify limits work as expected
  • ✓ Use the same Limit Name intentionally when coordinating across flows
  • ✓ Log Fail paths to monitor when limits are hit
  • ✓ Combine with other controls (authentication, validation) for security

Common Mistakes

MistakeSymptomFix 
Missing variables in Limit NameUsing limit_{{user}} but userId not in flow dictionaryEnsure variables populated before Limit Route stage
Unintended name collisionDifferent operations share limit by accidentUse specific names with context: action_entity_id
Not handling Fail pathFlow breaks when limit exceededAlways connect Fail exit with appropriate handling
Expecting exact timingAssuming millisecond precisionUse second-level granularity, add buffer for critical timing
Using for securityRelying on limit for critical constraintsCombine with database constraints; limit can fail open on errors
Expecting fixed windowsAssuming "top of minute" reset behaviorUnderstand sliding window model; resets from last Pass

Troubleshooting

IssueExit/ResultCommon CauseFix 
Rate limiting not workingAlways PassConnection errors to distributed storageCheck system health and logs for errors
Unexpected limit collisionsFail unexpectedlySame Limit Name used in different contextsUse more specific names with entity IDs
Two executions both PassBoth PassRace condition on simultaneous executionUse shorter windows or backend constraints for strict limits
Variable not resolvedIncorrect limitingVariable in Limit Name empty or undefinedVerify variables exist and have expected values

Edge Cases

  • Simultaneous executions: Two flows at exact same time might both Pass due to race condition
  • Connection errors: Routes to Pass (fail-open) when storage unavailable
  • Very short windows: Minimum 1 second; sub-second not supported
  • Default Limit Name: Different stages in same flow have different limits; copying stage creates new limit
  • Variable Limit Names: Empty variables result in names like limit__action

Related Stages

  • Limit Route Reset: Manually clear rate limit lock before expiration
  • Route Flow: Conditional branching based on values (vs rate-based branching)
  • Loop: Iterate with delays (alternative to rapid execution prevention)
  • Run Later: Schedule delayed execution (vs preventing execution)

Was this article helpful?