# How to Limit Workflow Triggers in n8n

- Tool: n8n
- Difficulty: Beginner
- Time required: 10-15 minutes
- Compatibility: n8n 1.20+ (self-hosted and Cloud)
- Last updated: March 2026

## TL;DR

To limit workflow triggers in n8n, use the Schedule Trigger node with a longer interval, add an IF node to deduplicate incoming data, or configure the Execution Settings to prevent overlapping runs. These techniques reduce unnecessary executions and keep your n8n instance responsive under load.

## Controlling How Often Workflows Fire in n8n

Workflows that trigger too frequently can overwhelm your n8n instance, burn through API quotas, and create duplicate data. Whether you are polling an inbox every few seconds or receiving bursts of webhook requests, you need strategies to throttle execution frequency. This tutorial covers three approaches: adjusting trigger intervals, deduplicating items with an IF node, and using n8n's built-in execution settings to prevent overlapping runs.

## Before you start

- A running n8n instance (v1.20 or later)
- At least one active workflow with a trigger node
- Basic familiarity with n8n expressions

## Step-by-step guide

### 1. Adjust the trigger interval on your Schedule Trigger node

Open your workflow and click the Schedule Trigger node. Change the Trigger Interval from a short value (like every 1 minute) to a longer one that matches your actual needs. For most polling use cases, every 5 or 15 minutes is sufficient. If you use a Cron expression, update it accordingly. For example, change */1 * * * * to */15 * * * * to run every 15 minutes instead of every minute. Click Execute Workflow to test that the new interval works, then toggle the workflow active.

**Expected result:** The workflow now triggers at the longer interval, reducing total executions per day.

### 2. Deduplicate incoming items using static data and an IF node

When a trigger like the Gmail Trigger or RSS Feed returns items you have already processed, you waste executions. Add a Code node after the trigger that checks each item's unique ID against a stored list using n8n's static data. Items already in the list are filtered out. New items are added to the list and passed through. This prevents reprocessing the same email, record, or event twice. The static data persists across executions, so the list survives workflow restarts.

```
// Code node — Run Once for All Items
const staticData = $getWorkflowStaticData('global');
if (!staticData.processedIds) {
  staticData.processedIds = [];
}

const newItems = [];
for (const item of $input.all()) {
  const id = item.json.id || item.json.messageId || '';
  if (id && !staticData.processedIds.includes(id)) {
    staticData.processedIds.push(id);
    newItems.push(item);
  }
}

// Keep only last 500 IDs to prevent memory growth
if (staticData.processedIds.length > 500) {
  staticData.processedIds = staticData.processedIds.slice(-500);
}

return newItems.length > 0 ? newItems : [];
```

**Expected result:** Only new, unprocessed items pass through. Previously seen items are silently dropped.

### 3. Prevent overlapping executions with workflow settings

If a workflow takes longer than the trigger interval, multiple instances can run at the same time, causing race conditions and duplicate processing. To prevent this, click the gear icon on the workflow canvas to open Workflow Settings. Under the Error Handling section, find the Save Execution Progress toggle and enable it. For self-hosted n8n, you can also set the environment variable EXECUTIONS_MODE=queue and configure concurrency limits. On n8n Cloud, use the workflow-level timeout setting to stop runaway executions. Set Timeout Workflow After to a reasonable value like 120 seconds.

**Expected result:** Only one instance of the workflow runs at a time, and executions that exceed the timeout are stopped automatically.

### 4. Add rate limiting for webhook-triggered workflows

If your workflow uses a Webhook trigger and receives bursts of requests, add a Code node that enforces a minimum interval between processed requests. Use static data to store the timestamp of the last processed request. If the current request arrives within the cooldown period, respond immediately with a 429 status and skip further processing. This protects downstream API calls from being overwhelmed by rapid webhook fires.

```
// Code node — Run Once for All Items
const staticData = $getWorkflowStaticData('global');
const COOLDOWN_MS = 5000; // 5 seconds between processed requests
const now = Date.now();

if (staticData.lastProcessed && (now - staticData.lastProcessed) < COOLDOWN_MS) {
  // Too soon — skip this execution
  return [];
}

staticData.lastProcessed = now;
return $input.all();
```

**Expected result:** Webhook requests arriving within the cooldown period are dropped. Only one request per interval is processed.

## Complete code example

File: `deduplication-with-rate-limit.js`

```javascript
// Code node: Combined Deduplication + Rate Limiting
// Mode: Run Once for All Items
// Place immediately after any trigger node

const staticData = $getWorkflowStaticData('global');

// Initialize storage
if (!staticData.processedIds) {
  staticData.processedIds = [];
}
if (!staticData.lastProcessed) {
  staticData.lastProcessed = 0;
}

// Rate limiting — minimum interval between executions
const COOLDOWN_MS = 5000;
const now = Date.now();

if ((now - staticData.lastProcessed) < COOLDOWN_MS) {
  return [];
}

// Deduplication — filter out already-seen items
const newItems = [];
for (const item of $input.all()) {
  const id = item.json.id
    || item.json.messageId
    || item.json.uid
    || JSON.stringify(item.json).substring(0, 100);

  if (!staticData.processedIds.includes(id)) {
    staticData.processedIds.push(id);
    newItems.push(item);
  }
}

// Prune old IDs to prevent unbounded growth
const MAX_IDS = 1000;
if (staticData.processedIds.length > MAX_IDS) {
  staticData.processedIds = staticData.processedIds.slice(-MAX_IDS);
}

// Update last-processed timestamp only if we have new items
if (newItems.length > 0) {
  staticData.lastProcessed = now;
}

return newItems;
```

## Common mistakes

- **Setting the trigger interval to every second for near-real-time processing** — undefined Fix: Use a Webhook trigger instead of polling for real-time needs. Polling every second creates unnecessary load.
- **Not pruning the deduplication ID list, causing memory to grow indefinitely** — undefined Fix: Add a slice operation to keep only the last 500-2000 IDs in static data.
- **Using workflow-level variables instead of static data for deduplication** — undefined Fix: Workflow-level variables reset each execution. Use $getWorkflowStaticData('global') which persists across runs.
- **Forgetting that deactivating and reactivating a workflow resets some triggers** — undefined Fix: After reactivation, triggers like the Gmail Trigger may re-fetch recent items. Always keep deduplication logic in place.

## Best practices

- Set trigger intervals based on actual business needs — polling every minute is rarely necessary
- Always deduplicate incoming items when using email, RSS, or database polling triggers
- Use n8n's static data to persist deduplication lists across workflow executions
- Prune your stored ID list periodically to prevent unbounded memory growth
- Set workflow timeouts to stop runaway executions from blocking the queue
- Use environment variable N8N_CONCURRENCY_PRODUCTION_LIMIT on self-hosted instances to cap parallel executions
- Monitor execution counts in the Executions tab to verify your limits are working

## Frequently asked questions

### Can I limit how many times a webhook-triggered workflow runs per minute?

Yes. Add a Code node after the Webhook trigger that uses static data to track the last execution timestamp and drops requests arriving within a cooldown period. You can also set N8N_CONCURRENCY_PRODUCTION_LIMIT as an environment variable on self-hosted instances.

### Does n8n have built-in rate limiting for triggers?

n8n does not have a built-in per-workflow rate limiter, but you can use execution concurrency settings and workflow timeouts to control how many workflows run simultaneously. For per-item deduplication, use a Code node with static data.

### What happens if my workflow takes longer than the trigger interval?

By default, n8n starts a new execution even if the previous one is still running. This can cause race conditions. Use queue mode with concurrency limits or add deduplication logic to prevent overlapping executions from processing the same data.

### How do I check how many times a workflow has been triggered today?

Open the Executions tab from the left sidebar in n8n. Filter by the specific workflow and the current date range. The list shows every execution with its start time, status, and duration.

### Will static data survive an n8n restart?

Yes, static data is persisted in the n8n database. It survives restarts, updates, and workflow deactivation/reactivation. It is only lost if you manually clear it or delete the workflow.

### Can RapidDev help me optimize my n8n workflow execution frequency?

Yes, RapidDev's engineering team can audit your n8n workflows and implement proper trigger management, deduplication, and concurrency controls to reduce unnecessary executions and prevent duplicate processing.

---

Source: https://www.rapidevelopers.com/n8n-tutorial/how-to-limit-workflow-triggers-in-n8n
© RapidDev — https://www.rapidevelopers.com/n8n-tutorial/how-to-limit-workflow-triggers-in-n8n
