---
title: "Limit Route"
url: "https://help.flows.world/en/article/limit-route"
language: "en"
last_updated: "2026-09-19T06:55:19.403Z"
---

# 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.

![](https://cdn-assets.productfruits.com/02c3bec9-6d79-4e9f-bc8b-75c2c7735b52)

**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

| Field | Description | Example |
| --- | --- | --- |
| **Time in Seconds** | How long the route stays locked after a run takes the Pass path | `3600` (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](https://help.flows.world/en/article/flows-functions) for the full list.

## Exit Points

| Exit | When |
| --- | --- |
| **Pass** | No lock is currently active (first run, or the previous window has expired). A new lock is created. |
| **Fail** | A 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

| Feature | Behavior |
| --- | --- |
| **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 Run** | Routes to Fail immediately; it does not wait or queue for the window to end |
| **Time Precision** | 1-second precision; sub-second windows aren't supported |
| **Window Type** | Sliding: resets from the last Pass, not a fixed clock time |
| **Fails Open** | If a technical issue prevents the check, the flow takes the Pass path rather than getting stuck |
| **No Output Variables** | The 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

| Mistake | Symptom | Fix |
| --- | --- | --- |
| Missing variables in the Limit Name | Using `limit_{{userId}}` but userId isn't set yet | Make sure the variable has a value before this stage runs |
| Unintended name collision | Two different actions share a limit by accident | Use a specific name that includes context, e.g. `action_entity_id` |
| Not handling the Fail path | The flow appears to break when the limit is hit | Always connect the Fail exit to appropriate handling |
| Expecting exact timing | Assuming millisecond precision | Work at the second level and add buffer for anything time-sensitive |
| Relying on it for security | Treating the limit as a strict guarantee | Combine with database-level constraints for anything critical; this stage can fail open |
| Expecting fixed windows | Assuming a "top of the hour" style reset | Remember the window is sliding and resets from the last Pass |

## Troubleshooting

| Issue | Common Cause | Fix |
| --- | --- | --- |
| Limit doesn't seem to apply; always Pass | A temporary technical issue caused the stage to fail open | If this keeps happening, contact your Flows support contact |
| Unexpected limit collisions | The same Limit Name is used for two different things | Use a more specific name that includes an entity ID |
| Variable not resolving in the Limit Name | The variable was empty or not set yet | Confirm the variable has a value before this stage runs |
| Limit resets sooner or later than expected | The sliding window resets from the last Pass, not a fixed clock time | Plan 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**](https://help.flows.world/en/article/reset-limit)**:** Manually clear a lock before it expires
-   [**Route Flow**](https://help.flows.world/en/article/route-flow)**:** Branch based on variable values instead of execution rate
-   [**Loop**](https://help.flows.world/en/article/loop)**:** Repeat part of a flow, with delays between iterations
-   [**Run Later**](https://help.flows.world/en/article/run-later)**:** Schedule delayed execution instead of blocking it
