Use cases
- Limit how many runs of a task execute at once: Setting task concurrency
- Share one limit across several tasks: Sharing a limit between tasks
- Give each tenant its own separate concurrency: Concurrency keys and per-tenant limits
- Per-tenant limits with a ceiling on the total: Per-key and total limits together
- Cap a tenant across every task they run: A per-tenant cap across multiple tasks
- Cap a shared resource, like an external API, across tasks and tenants: A global cap for a shared resource
- Switch a run’s limits when you trigger it: Setting limits when you trigger a run
Default concurrency
By default, all tasks have an unbounded concurrency limit, limited only by the overall concurrency limits of your environment.Your environment has a base concurrency limit and a burstable limit (default burst factor of 2.0x
the base limit). Individual tasks and limits are capped by the base concurrency limit, not the
burstable limit. For example, if your base limit is 10, your environment can burst up to 20
concurrent runs, but any single limit can allow at most 10 concurrent runs. If you’re a paying
customer you can request higher burst limits by contacting us.
Setting task concurrency
Set theconcurrency option on a task to limit how many of its runs execute at once. { total: n } caps the task outright:
/trigger/one-at-a-time.ts
totalcaps every run of the task together, whether or not runs use aconcurrencyKey.perKeycaps eachconcurrencyKeypool separately; runs triggered without a key share one pool.
/trigger/per-user.ts
The
queue: {"{ concurrencyLimit: n }"} option keeps working but is deprecated in favor of
concurrency. Its single number means “per key when runs pass a concurrencyKey, whole queue
when they don’t” — the concurrency shape says which you mean explicitly.Sharing a limit between tasks
Declare a named limit withconcurrencyLimit() and put it in each task’s concurrency. Every task holding the limit draws from the same pools:
/trigger/limits.ts
concurrency takes a single item or an array: at most one inline shape (which caps that task alone) plus up to two named limits. A run starts only when every limit it holds has capacity, and it occupies a slot in each while it executes:
/trigger/summarize.ts
Names you declare with
concurrencyLimit() are 1-122 characters using only letters, numbers,
underscores and hyphens.Setting limits when you trigger a run
The trigger-timeconcurrency option takes limit names and replaces the task’s declared named limits for that run. The task’s inline limit always applies:
app/api/report/route.ts
Concurrency keys and per-tenant limits
If you’re building an application where you want to run tasks for your users, you might want a separate limit for each of your users (or orgs, projects, etc.). You can do this by passing aconcurrencyKey when you trigger. Each unique key value gets its own pool under every perKey bound the run holds:
app/api/report/route.ts

