Concurrency & Queues
Control how many task runs execute simultaneously.
Default Behavior
- Each task gets its own queue by default
- Unbounded concurrency — limited only by environment limits
- Environment has a base limit and burstable limit (default 2× base)
- Only actively executing runs count against concurrency
Setting Task Concurrency
ts
export const oneAtATime = task({
id: "one-at-a-time",
queue: { concurrencyLimit: 1 },
run: async (payload) => { /* ... */ },
});Sharing Queues Between Tasks
ts
import { queue, task } from "@trigger.dev/sdk";
export const myQueue = queue({
name: "my-queue",
concurrencyLimit: 1,
});
export const task1 = task({ id: "task-1", queue: myQueue, run: async (payload) => { /* ... */ } });
export const task2 = task({ id: "task-2", queue: myQueue, run: async (payload) => { /* ... */ } });
// Only one of task1 or task2 runs at a timeOverride Queue at Trigger Time
ts
// Default: 1 at a time
const handle = await generatePullRequest.trigger(data);
// Priority: use a dedicated paid queue
const handle = await generatePullRequest.trigger(data, {
queue: { name: "paid-users", concurrencyLimit: 10 },
});Per-Tenant Queuing with concurrencyKey
Create a separate queue instance per user or organization:
ts
// Free users: 1 concurrent run per user
await generatePullRequest.trigger(data, {
queue: "free-users",
concurrencyKey: data.userId,
});
// Paid users: 10 concurrent runs per user
await generatePullRequest.trigger(data, {
queue: "paid-users",
concurrencyKey: data.userId,
});Concurrency and Waits
When a task reaches a wait (triggerAndWait, wait.for, etc.) it releases its concurrency slot:
ts
export const parentTask = task({
id: "parent-task",
queue: { concurrencyLimit: 1 },
run: async (payload) => {
await subtask.triggerAndWait(payload);
// Parent checkpointed here — releases slot
// Another run of parentTask can now start!
},
});Subtasks and Queues
Subtasks do NOT inherit the parent's queue — they run on their own queue.
Managing Queues with the SDK
ts
import { queues } from "@trigger.dev/sdk";
// List queues
const allQueues = await queues.list();
const page = await queues.list({ page: 1, perPage: 20 });
// Retrieve a queue
const q1 = await queues.retrieve("queue_1234");
const q2 = await queues.retrieve({ type: "task", name: "my-task-id" });
const q3 = await queues.retrieve({ type: "custom", name: "my-custom-queue" });
// Queue object properties:
// id, name, type, running, queued, paused,
// concurrencyLimit, concurrency: { current, base, override }
// Pause / Resume
await queues.pause("queue_1234");
await queues.resume({ type: "task", name: "my-task-id" });
// Override concurrency
await queues.overrideConcurrencyLimit("queue_1234", 5);
await queues.overrideConcurrencyLimit({ type: "task", name: "my-task-id" }, 20);
// Reset to base
await queues.resetConcurrencyLimit("queue_1234");