inngest-flow-control
This skill provides Inngest flow control mechanisms to manage API rate limits, prevent duplicate processing, and ensure fair resource allocation.
Identity proven by GitHub's verified organisation badge (inngest)
- Agents
- Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, claude.ai and API
- License
- Apache-2.0 (permissive)
- Pin
- 082798apinned Oct 9, 2026
- Context cost
- about 2,100 tokenswhen the skill loads
- GitHub stars
- 28on inngest/inngest-skills
- Scripts
- None found
What it does
“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.”
Generated summary from the skill's own text
This skill provides Inngest flow control mechanisms to manage API rate limits, prevent duplicate processing, and ensure fair resource allocation. It covers concurrency limits with keying for multi-tenant scenarios, throttling to spread function starts, rate limiting to discard excessive events, debouncing for bursty input, priority queuing, singleton enforcement, and event batching. These tools help prevent system overload and ensure reliable event processing.
When to use it
- Handle external API rate limits like OpenAI, HubSpot, or Stripe
- Prevent duplicate work from rapid event bursts or user actions
- Ensure per-tenant fairness and prevent noisy neighbor issues
- Batch events for efficiency or add priority to important runs
When not to
- No flow control needed for simple synchronous operations
- Python or Go projects should use language-specific guidance instead
Install
These commands install from the publisher's repository and need no account.
skills CLI
npx skills add inngest/inngest-skills --skill inngest-flow-controlInstalls from the repository's default branch, which may have changed since the commit we checked.
GitHub CLI 2.90 or later
gh skill install inngest/inngest-skills inngest-flow-control@082798a627bbe9c3ed3a6638a9f56116a035f122Installs the commit we checked (082798a).
Copy by hand
Download the folder at 082798a and put it in .claude/skills/inngest-flow-control for Claude Code and in .agents/skills/inngest-flow-control for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.
Copy for your agent
A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.
Prompt
Install the agent skill "inngest-flow-control" by Inngest. Source, pinned to commit 082798a627bbe9c3ed3a6638a9f56116a035f122: https://github.com/inngest/inngest-skills/tree/082798a627bbe9c3ed3a6638a9f56116a035f122/skills/inngest-flow-control 1. Download that folder at exactly this commit. Do not use the default branch. 2. Copy every file unchanged, keeping the folder structure, into .claude/skills/inngest-flow-control/ for Claude Code and .agents/skills/inngest-flow-control/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist. 3. Do not edit the files, and do not run any script in the folder unless I ask you to. 4. When you are done, list the files you copied and where you put them. Listing and checks: https://www.agentnative.dev/skills/inngest/inngest-flow-control-inngest-skills
SKILL.md at the pin
---
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.
From inngest/inngest-skills at 082798a, shown as plain text under its license: Apache-2.0 (permissive). The license text is in LICENSE.
View SKILL.md on GitHub at 082798aFiles
- SKILL.md8.9 KB · be1891d43213
1 file, 8.9 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.
Skill folder on GitHub at 082798aAlso in
The same SKILL.md content appears in these places too. We list it once and credit the oldest public source.
More from Inngest
inngest-agent-evals
Builds production evaluation workflows for AI agents on Inngest using direct and deferred scoring, sessions for grouping related runs, step experiments for…
Claude Code, Codex, Cursor +4 · about 2.6K tokens · pinned 6 days ago
inngest-agents
Build durable AI agents and multi-step agentic workflows using Inngest and AgentKit.
Claude Code, Codex, Cursor +4 · about 2.1K tokens · pinned 6 days ago
inngest-api-cli
This skill routes the agent to use the Inngest CLI `inngest api` command for operational tasks like debugging runs, querying events, syncing apps, invoking…
Claude Code, Codex, Cursor +4 · about 1.9K tokens · pinned 6 days ago
inngest-api
This skill enables agents to interact with the Inngest REST API v2 for Cloud operations, raw HTTP requests, and API reference lookups.
Claude Code, Codex, Cursor +4 · about 1.1K tokens · pinned 6 days ago
inngest-brownfield-audit
This skill audits existing TypeScript or JavaScript codebases to identify where Inngest can improve reliability and durability.
Claude Code, Codex, Cursor +4 · about 2.5K tokens · pinned 6 days ago
inngest-cli
This skill enables installation and operation of the Inngest CLI for local development and testing with the Dev Server, which provides a browser UI at…
Claude Code, Codex, Cursor +4 · about 3.4K tokens · pinned 6 days ago
Related in Backend and APIs
inngest-events
This skill teaches event design and delivery patterns for Inngest, covering event payload structure, naming conventions, idempotency with event IDs, scheduled…
by InngestOfficial publisher
Claude Code, Codex, Cursor +4 · about 2.9K tokens · pinned 6 days ago
inngest-middleware
This skill teaches how to implement middleware in Inngest durable functions to handle cross-cutting concerns like structured logging, error tracking…
by InngestOfficial publisher
Claude Code, Codex, Cursor +4 · about 2.4K tokens · pinned 6 days ago
wix-headless
This skill configures Wix backend services (Stores, Bookings, CMS, Blog, Events, Forms, etc.) for a Wix Headless frontend by inferring needed capabilities…
by Wix.comOfficial publisher
Contains scripts
Claude Code, Codex, Cursor +3 · about 3.8K tokens · pinned 6 days ago
inngest-durable-functions
Build fault-tolerant, long-running workflows using Inngest's durable execution model in TypeScript.
by InngestOfficial publisher
Claude Code, Codex, Cursor +4 · about 3.5K tokens · pinned 6 days ago
inngest-realtime
Stream live updates from Inngest v4 durable workflows to browser UIs via typed channels and topics.
by InngestOfficial publisher
Claude Code, Codex, Cursor +4 · about 4.5K tokens · pinned 6 days ago
inngest-setup
This skill sets up Inngest, a durable execution platform, in TypeScript projects for building retry-safe webhook handlers, background jobs, and scheduled tasks.
by InngestOfficial publisher
Claude Code, Codex, Cursor +4 · about 2.9K tokens · pinned 6 days ago
Open roles at Inngest
No open roles at Inngest on the Agent Native jobs board right now.
Browse the jobs board