Limit Route

Overview

Limit route lets a flow pass through this point only once per time window you choose. After a run takes the Pass path, the route is locked for the duration you set; any run that arrives before the window ends takes the Fail path instead. Use it for rate limiting, cooldowns, deduplication, and throttling expensive actions.

Where to find it: Flow Control in the stage library.

When to Use

  • Prevent duplicate actions within a time window
  • Rate limit per user, per request, or per any other entity
  • Throttle expensive operations, such as API calls or emails
  • Enforce a cooldown period between actions
  • Protect against rapid, repeated executions or accidental spam
  • Debounce a flow that's triggered repeatedly in quick succession

Configuration

Required Fields

FieldDescriptionExample
Time in SecondsHow long the route stays locked after a run takes the Pass path3600 (1 hour), 300 (5 minutes)

Optional Fields

  • Limit Name (Advanced): A custom identifier for this lock. If left blank, it defaults to a name based on the stage and flow. Use the same Limit Name across different flows to share one limit between them. Can include {{variables}} for per-user or per-entity limits, e.g. email_sent_{{userId}}.
  • Comment: Documentation only, no effect on how the stage runs.

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
PassNo lock is currently active (first run, or the previous window has expired). A new lock is created.
FailA lock is already active. The run takes Fail immediately - it does not wait or queue for the window to end and then pass. Route to alternative handling or a message for the user. If you want a delayed retry, send the Fail path to Run Later or Wait a while yourself.

How It Works

When executed, the stage:

  1. Resolves the Limit Name - Uses your custom name if provided, otherwise a name based on the stage and flow, always scoped to your workspace
  2. Checks and creates the lock in one step - So two runs that arrive at almost the same instant can't both slip through; only one of them takes the Pass path
  3. Routes based on the result - No lock existed: takes Pass and creates a new one. A lock already existed: takes Fail
  4. Lets the lock expire automatically - After the Time in Seconds you set, the next run after that takes Pass again

Rate limiting model: Sliding window. The window restarts every time a run takes the Pass path, it isn't tied to a fixed clock time like the top of the hour.

Examples

1. Prevent Duplicate Email Sends

  • Limit Name: email_sent_{{userId}}
  • Time in Seconds: 3600 (1 hour)
  • Pass path: Send Email → End
  • Fail path: End (skip the email)
  • Result: At most one email per hour per user

2. API Rate Limiting

  • Limit Name: api_call_limit
  • Time in Seconds: 6 (enforces roughly 10 calls per minute)
  • Pass path: Call API → continue
  • Fail path: return an error message
  • Result: At least 6 seconds between calls

3. User Action Cooldown

  • Limit Name: reward_claimed_{{userId}}
  • Time in Seconds: 86400 (24 hours)
  • Pass path: save the reward
  • Fail path: return "Already claimed today"
  • Result: One reward claim per day per user

4. Shared Limit Across Flows

  • Limit Name: notification_limit_{{userId}} (used the same way in every flow)
  • Time in Seconds: 3600
  • Flows: order confirmations, marketing, system alerts
  • Result: All three flows share one limit and coordinate automatically

5. Debouncing Rapid Triggers

  • Limit Name: file_process_{{fileId}}
  • Time in Seconds: 30
  • Pass path: process the file
  • Fail path: ignore the rapid change
  • Result: The file is processed at most once every 30 seconds, no matter how often it changes

Key Behaviors

FeatureBehavior
Distributed✓ Works across every server behind your workspace; the limit is shared, not per-server
Workspace Isolation✓ Limits are scoped to your workspace; other workspaces can't affect or see yours
No Race Condition✓ Checking for a lock and creating one happen as a single step, so two simultaneous runs can't both take Pass
Blocked RunRoutes to Fail immediately; it does not wait or queue for the window to end
Time Precision1-second precision; sub-second windows aren't supported
Window TypeSliding: resets from the last Pass, not a fixed clock time
Fails OpenIf a technical issue prevents the check, the flow takes the Pass path rather than getting stuck
No Output VariablesThe stage doesn't add any data to the flow; it only routes Pass or Fail

Best Practices

  • ✓ Use descriptive Limit Names that make it clear what's being limited
  • ✓ Include an entity ID in the name for per-user or per-item limits, e.g. {{userId}}
  • ✓ Choose a time window that balances protection with a good user experience
  • ✓ Always handle the Fail path with a clear message or fallback action
  • ✓ Reuse the same Limit Name across flows only when you want them to share one limit
  • ✓ Combine with other controls, such as authentication, for anything security-critical

Common Mistakes

MistakeSymptomFix
Missing variables in the Limit NameUsing limit_{{userId}} but userId isn't set yetMake sure the variable has a value before this stage runs
Unintended name collisionTwo different actions share a limit by accidentUse a specific name that includes context, e.g. action_entity_id
Not handling the Fail pathThe flow appears to break when the limit is hitAlways connect the Fail exit to appropriate handling
Expecting exact timingAssuming millisecond precisionWork at the second level and add buffer for anything time-sensitive
Relying on it for securityTreating the limit as a strict guaranteeCombine with database-level constraints for anything critical; this stage can fail open
Expecting fixed windowsAssuming a "top of the hour" style resetRemember the window is sliding and resets from the last Pass

Troubleshooting

IssueCommon CauseFix
Limit doesn't seem to apply; always PassA temporary technical issue caused the stage to fail openIf this keeps happening, contact your Flows support contact
Unexpected limit collisionsThe same Limit Name is used for two different thingsUse a more specific name that includes an entity ID
Variable not resolving in the Limit NameThe variable was empty or not set yetConfirm the variable has a value before this stage runs
Limit resets sooner or later than expectedThe sliding window resets from the last Pass, not a fixed clock timePlan around the last successful run rather than calendar time

Edge Cases

  • Very short windows: Minimum is 1 second; sub-second windows aren't supported
  • Default Limit Name: Different stages in the same flow have independent limits; copying a stage to a new flow creates a new limit
  • Empty variable in the name: Results in a name with a gap, e.g. limit__action; make sure variables resolve as expected
  • Manual reset: A lock can be cleared early with the Limit route Reset stage; use carefully so it doesn't defeat the purpose of the limit

Related Stages

  • Reset Limit: Manually clear a lock before it expires
  • Route Flow: Branch based on variable values instead of execution rate
  • Loop: Repeat part of a flow, with delays between iterations
  • Run Later: Schedule delayed execution instead of blocking it