К основному содержанию
скилл CX Codex

inngest-flow-control — скилл для Claude Code: лимиты и очереди Inngest

Скилл по flow control в Inngest: concurrency, throttling, rate limiting, debounce, priority, singleton и батчинг событий. Пригодится, когда внешние API отвечают 429.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add inngest/inngest-skills --skill inngest-flow-control -a claude-code
Открыть на GitHub

Что делает inngest-flow-control

Скилл разбирает механизмы управления потоком запусков в Inngest и даёт готовые примеры на TypeScript. Внутри — короткий навигатор по выбору опции: ограничить одновременные запуски, растянуть их во времени, отбрасывать лишние, ждать затишья, группировать события. Дальше по каждому пункту идёт код inngest.createFunction с параметрами.

Concurrency ограничивает не запуски функций, а выполнение шагов: функция, которая висит на step.sleep() или step.waitForEvent(), в лимит не попадает. Ключ key включает лимит на каждое значение, а scope: "account" делит общую квоту между функциями — удобно, когда несколько из них ходят в один внешний API. Throttling задаёт старты за период с запасом на burst, rate limiting события отбрасывает, а не откладывает, поэтому для вебхуков это защита от дублей, а не сглаживание пиков.

Debounce ждёт, пока события перестанут приходить, и берёт последнее; timeout заставляет сохранить результат, даже если правки не прекратились. Priority поднимает запуск в очереди по выражению от данных события, singleton оставляет один экземпляр на ключ. Скиллы написаны под TypeScript — для Python и Go авторы отправляют к документации Inngest, так что на другом языке примеры придётся переносить самому.

Какие задачи решает

  • удержать лимит внешнего API, когда несколько функций бьют в один сервис
  • не плодить дубли при шквале вебхуков
  • дождаться, пока пользователь закончит править документ, и сохранить один раз
  • дать каждому арендатору свою долю запусков без шумных соседей
  • пропустить VIP-заказ вперёд обычных

Примеры запросов агенту

  • Настрой concurrency с ключом по user_id, чтобы по одному пользователю шёл только один шаг
  • Добавь throttling на 10 стартов в минуту с ключом по customer_id для синхронизации с CRM
  • Поставь debounce на 5 минут по document_id, чтобы сохранение срабатывало после последней правки

Как установить inngest-flow-control

1Через Skills CLI (Vercel)

npx skills add inngest/inngest-skills --skill inngest-flow-control -a claude-code

2Вручную: положить файлы

~/.claude/skills/inngest-flow-control/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/inngest-flow-control/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о inngest-flow-control

Как установить inngest-flow-control в Claude?

Выполните npx skills add inngest/inngest-skills --skill inngest-flow-control -a claude-code. Скилл появится в ~/.claude/skills/inngest-flow-control/SKILL.md.

Что делает inngest-flow-control?

Описывает опции flow control в Inngest — concurrency с ключами, throttling, rate limiting, debounce, priority, singleton и батчинг событий — и показывает, когда какую брать.

На каком языке примеры в скилле?

На TypeScript. Для Python и Go авторы скилла советуют смотреть документацию Inngest: сами концепции переносятся, а синтаксис отличается.

Исходный текст

SKILL.md · Apache-2.0
---
name: inngest-flow-control
description: "Use when handling external API rate limits (e.g., OpenAI 429s, HubSpot or Stripe rate limits), preventing duplicate work from rapid event bursts (debouncing user actions), spreading load over time, ensuring per-tenant fairness, processing events in batches, limiting concurrent runs of the same operation, or assigning priority to important runs. Covers Inngest flow control: concurrency limits with keys, throttling, rate limiting, debounce, priority, singleton, and event batching."
---

# Inngest Flow Control

Master Inngest flow control mechanisms to manage resources, prevent overloading systems, and ensure application reliability. This skill covers all flow control options with prescriptive guidance on when and how to use each.

> **These skills are focused on TypeScript.** For Python or Go, refer to the [Inngest documentation](https://www.inngest.com/llms.txt) for language-specific guidance. Core concepts apply across all languages.

## Quick Decision Guide

- **"Limit how many run at once"** → Concurrency
- **"Spread runs over time"** → Throttling
- **"Block after N runs in a period"** → Rate Limiting
- **"Wait for activity to stop, then run once"** → Debounce
- **"Only one run at a time for this key"** → Singleton
- **"Process events in groups"** → Batching
- **"Some runs are more important"** → Priority

## Concurrency

**When to use:** Limit the number of executing steps (not function runs) to manage computing resources and prevent system overwhelm.

**Key insight:** Concurrency limits active code execution, not function runs. A function waiting on `step.sleep()` or `step.waitForEvent()` doesn't count against the limit.

### Basic Concurrency

```typescript
inngest.createFunction(
  {
    id: "process-images",
    concurrency: 5,
    triggers: [{ event: "media/image.uploaded" }]
  },
  async ({ event, step }) => {
    // Only 5 steps can execute simultaneously
    await step.run("resize", () => resizeImage(event.data.imageUrl));
  }
);
```

### Concurrency with Keys (Multi-tenant)

Use `key` parameter to apply limit per unique value of the key.

```typescript
inngest.createFunction(
  {
    id: "user-sync",
    concurrency: [
      {
        key: "event.data.user_id",
        limit: 1
      }
    ],
    triggers: [{ event: "user/profile.updated" }]
  },
  async ({ event, step }) => {
    // Only 1 step per user can execute at once
    // Prevents race conditions in user-specific operations
  }
);
```

### Account-level Shared Limits

```typescript
inngest.createFunction(
  {
    id: "ai-summary",
    concurrency: [
      {
        scope: "account",
        key: `"openai"`,
        limit: 60
      }
    ],
    triggers: [{ event: "ai/summary.requested" }]
  },
  async ({ event, step }) => {
    // Share 60 concurrent OpenAI calls across all functions
  }
);
```

**When to use each:**

- Basic: Protect databases or limit general capacity
- Keyed: Multi-tenant fairness, prevent "noisy neighbor" issues
- Account-level: Share quotas across multiple functions (API limits)

## Throttling

**When to use:** Control the rate of function starts over time to work around API rate limits or smooth traffic spikes.

**Key difference from concurrency:** Throttling limits function run starts; concurrency limits step execution.

```typescript
inngest.createFunction(
  {
    id: "sync-crm-data",
    throttle: {
      limit: 10, // 10 function starts
      period: "60s", // per minute
      burst: 5, // plus 5 immediate bursts
      key: "event.data.customer_id" // per customer
    },
    triggers: [{ event: "crm/contact.updated" }]
  },
  async ({ event, step }) => {
    // Respects CRM API rate limits: 10 calls/min per customer
    await step.run("sync", () => crmApi.updateContact(event.data));
  }
);
```

**Configuration:**

- `limit`: Functions that can start per period
- `period`: Time window (1s to 7d)
- `burst`: Extra immediate starts allowed
- `key`: Apply limits per unique key value

## Rate Limiting

**When to use:** Hard limit to prevent abuse or skip excessive duplicate events.

**Key difference from throttling:** Rate limiting discards events; throttling delays them.

```typescript
inngest.createFunction(
  {
    id: "webhook-processor",
    rateLimit: {
      limit: 1,
      period: "4h",
      key: "event.data.webhook_id"
    },
    triggers: [{ event: "webhook/data.received" }]
  },
  async ({ event, step }) => {
    // Process each webhook only once per 4 hours
    // Prevents duplicate webhook spam
  }
);
```

**Use cases:**

- Prevent webhook duplicates
- Limit expensive operations per user
- Protection against abuse

## Debounce

**When to use:** Wait for a series of events to stop arriving before processing the latest one.

```typescript
inngest.createFunction(
  {
    id: "save-document",
    debounce: {
      period: "5m", // Wait 5min after last edit
      key: "event.data.document_id",
      timeout: "30m" // Force save after 30min max
    },
    triggers: [{ event: "document/content.changed" }]
  },
  async ({ event, step }) => {
    // Saves document only after user stops editing
    // Uses the LAST event received
    await step.run("save", () => saveDocument(event.data));
  }
);
```

**Perfect for:**

- User input that changes rapidly (search, document editing)
- Noisy webhook events
- Ensuring latest data is processed

## Priority

**When to use:** Execute some function runs ahead of others based on dynamic data.

```typescript
inngest.createFunction(
  {
    id: "process-order",
    priority: {
      // VIP users get priority up to 120 seconds ahead
      run: "event.data.user_tier == 'vip' ? 120 : 0"
    },
    triggers: [{ event: "order/placed" }]
  },
  async ({ event, step }) => {
    // VIP orders jump ahead in the queue
  }
);
```

**Advanced example:**

```typescript
inngest.createFunction(
  {
    id: "support-ticket",
    priority: {
      run: `
        event.data.severity == 'critical' ? 300 :
        event.data.severity == 'high' ? 120 :
        event.data.user_plan == 'enterprise' ? 60 : 0
      `
    },
    triggers: [{ event: "support/ticket.created" }]
  },
  async ({ event, step }) => {
    // Critical tickets get highest priority (300s ahead)
    // High severity: 120s ahead
    // Enterprise users: 60s ahead
    // Everyone else: normal priority
  }
);
```

## Singleton

**When to use:** Ensure only one instance of a function runs at a time.

### Skip Mode (Preserve Current Run)

```typescript
inngest.createFunction(
  {
    id: "data-backup",
    singleton: {
      key: "event.data.database_id",
      mode: "skip"
    },
    triggers: [{ event: "backup/requested" }]
  },
  async ({ event, step }) => {
    // Skip new backups if one is already running for this database
    await step.run("backup", () => performBackup(event.data.database_id));
  }
);
```

### Cancel Mode (Use Latest Event)

```typescript
inngest.createFunction(
  {
    id: "realtime-sync",
    singleton: {
      key: "event.data.user_id",
      mode: "cancel"
    },
    triggers: [{ event: "user/data.changed" }]
  },
  async ({ event, step }) => {
    // Cancel previous sync and start with latest data
    await step.run("sync", () => syncUserData(event.data));
  }
);
```

## Batching

**When to use:** Process multiple events together for efficiency.

```typescript
inngest.createFunction(
  {
    id: "bulk-email-send",
    batchEvents: {
      maxSize: 100, // Up to 100 events
      timeout: "30s", // Or 30 seconds, whichever first
      // `key` groups events into separate batches per unique value
      // This is different from expressions `if` which filters events
      key: "event.data.campaign_id" // Batch per campaign
    },
    triggers: [{ event: "email/send.queued" }]
  },
  async ({ events, step }) => {
    // Process array of events together
    const emails = events.map((evt) => ({
      to: evt.data.email,
      subject: evt.data.subject,
      body: evt.data.body
    }));

    await step.run("send-batch", () => emailService.sendBulk(emails));
  }
);
```

## Combining Flow Control

### Example: Fair AI Processing

```typescript
inngest.createFunction(
  {
    id: "ai-image-processing",
    // Global throttling for API limits
    throttle: {
      limit: 50,
      period: "60s",
      key: `"gpu-cluster"`
    },
    // Per-user concurrency for fairness
    concurrency: [
      {
        key: "event.data.user_id",
        limit: 3
      }
    ],
    // VIP users get priority
    priority: {
      run: "event.data.plan == 'pro' ? 60 : 0"
    },
    triggers: [{ event: "ai/image.generate" }]
  },
  async ({ event, step }) => {
    // Combines multiple flow controls for optimal resource usage
  }
);
```

**Pro tip:** Most production functions benefit from combining 1-3 flow control mechanisms for optimal reliability and performance.

© inngest · Apache-2.0 · inngest/inngest-skills

Похожие скиллы

Всё по теме «Бэкенд и API» →
inngest sickn33 Скилл для работы с Inngest: настраивай фоновые задачи, event-driven workflows и долгоживущие процессы без управления очередями и воркерами. Пригодится, если нужны отложенные операции, многошаговые workflow или обработка вебхуков. CX Codex +1 1 200установок cash-flow-snapshot официальный anthropics Строит прогноз движения денег на три месяца вперёд из данных бухучёта, платёжных систем или загруженного CSV. Показывает диапазон вероятных остатков, флагирует риски просрочек и нехватки денег на зарплату. CX Codex +1 1 900установок post-purchase-upsell-flow autonnel Проектирует воронки допродаж в один клик после чекаута, поднимая средний чек без риска для конверсии основного заказа. Помогает настроить апселлы, даунселлы и техническую логику платежей. CX Codex +1 103 100установок go-control-flow cxuu Скилл учит агента писать канонические циклы, ветвления и switch в Go. Пригодится при оформлении guard clauses и предотвращении багов с затенением переменных. CX Codex +1 1 200установок trigger-tasks triggerdotdev Помогает писать фоновые задачи для Trigger.dev через @trigger.dev/sdk. Пригодится при настройке повторов, очередей, cron-расписаний и валидации схем в каталоге /trigger. CX Codex +1 3 200установок trigger-setup triggerdotdev Помогает настроить Trigger.dev в проекте с нуля: создаёт конфигурационные файлы, подключает пакеты и подготавливает первую фоновую задачу. CX Codex +1 2 800установок

Из того же набора10

inngest-events Помогает проектировать событийные воркфлоу Inngest: имена событий, идемпотентность по id, fan-out и системные события. CX Codex +1 3 800установок inngest-durable-functions Скилл учит агента писать отказоустойчивые функции Inngest: шаги, мемоизация, ретраи, идемпотентность и отмена. CX Codex +1 3 800установок inngest-setup Скилл ставит Inngest в TypeScript-проект: клиент, переменные окружения, serve-эндпоинты и локальный dev-сервер. Пригодится, когда нужны фоновые задачи и вебхуки, переживающие падение процесса. CX Codex +1 3 700установок inngest-middleware Скилл учит ИИ настраивать middleware для Inngest v4: внедрять зависимости в обработчики и шифровать полезную нагрузку функций. CX Codex +1 3 600установок inngest-realtime Скилл учит агента публиковать обновления из durable-функций Inngest в живой интерфейс: статусы заказов, стриминг токенов, логи и подтверждения от пользователя. CX Codex +1 797установок inngest-api-cli Скилл учит агента работать с ресурсами Inngest через npx inngest-cli@latest api: разбирать запуски, искать события, синхронизировать приложения. CX Codex +1 776установок inngest-agents Скилл для сборки и отладки агентов на Inngest и AgentKit: вызовы моделей, инструменты, ожидание одобрения человека, прогресс в реальном времени. CX Codex +1 657установок inngest-brownfield-audit Разбирает существующий TypeScript- или JavaScript-проект и показывает, где фоновая работа теряется при деплое или падении процесса. CX Codex +1 659установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой