Run multiple tasks together: simultaneously, one at a time, or combined into one agent session.
Select multiple tasks from the board using checkboxes, then choose a mode from the floating control bar.
API: POST /api/batches
{
"taskIds": ["uuid-1", "uuid-2", "uuid-3"],
"mode": "parallel"
}Maximum 20 tasks per batch request.
Runs up to maxConcurrent tasks at the same time (configured in Settings, default 3). When a task finishes, the next queued task starts automatically.
Runs tasks strictly one at a time. Two sub-modes:
- Auto-approve (
queueAutoApprove: true): the next task starts immediately when the current one finishes. - Manual approval (
queueAutoApprove: false): waits for the user to approve the next task viaPOST /api/batches/:id/approve.
Runs all selected tasks in one OpenCode session with one combined prompt. Combined mode uses one worktree and one branch for the whole selected set, then marks all selected tasks Done together when the session completes with committable changes. If the combined session fails, no selected task is marked Done.
Unlike single-task execution (which uses a full shallow clone), batch execution uses git worktrees for efficiency:
- A bare clone is created (or fetched) as the main repo at
{REPOS_DIR}/{projectId}/.main - Parallel and Queue tasks each get their own worktree at
{REPOS_DIR}/{projectId}/batch-{batchId}/task-{taskId} - Combined mode gets one worktree at
{REPOS_DIR}/{projectId}/batch-{batchId}/combined - Parallel and Queue tasks use per-task branches:
openlinear/{taskId} - Combined mode uses the batch branch directly:
openlinear/batch-{batchId}
This means multiple tasks can work in the same repo simultaneously without conflicts during execution.
When all tasks complete, the batch enters the merge phase:
- For Parallel and Queue, create a batch branch:
openlinear/batch-{batchId}from the default branch - For each completed Parallel or Queue task, merge its branch into the batch branch
- For Combined, use the already-committed batch branch directly
- Push the batch branch
- Create a single PR containing all completed changes
| Setting | Behavior |
|---|---|
skip (default) |
Conflicting tasks are skipped; remaining tasks are included in the PR |
fail |
First conflict fails the entire batch; no PR is created |
queued -> running -> completed
-> failed
-> skipped (merge conflict with skip mode)
-> cancelled (manual cancel)
pending -> running -> merging -> completed
-> failed
-> cancelled
When stopOnFailure is enabled, the batch is cancelled as soon as any task fails. All remaining queued tasks are not started.
| Method | Path | Description |
|---|---|---|
POST |
/api/batches |
Create and start a batch |
GET |
/api/batches |
List active batches |
GET |
/api/batches/:id |
Get batch status with per-task progress |
POST |
/api/batches/:id/cancel |
Cancel entire batch |
POST |
/api/batches/:id/tasks/:taskId/cancel |
Cancel one task in a batch |
POST |
/api/batches/:id/approve |
Approve next task (queue mode) |
batch:created-- batch initializedbatch:started-- execution beginsbatch:task:started-- individual task startsbatch:task:completed-- individual task finishes successfullybatch:task:failed-- individual task failsbatch:task:skipped-- task skipped due to merge conflictbatch:task:cancelled-- individual task cancelledbatch:merging-- merge phase startedbatch:completed-- batch done, PR createdbatch:failed-- batch failed (conflict in fail mode or fatal error)batch:cancelled-- batch cancelled by user
{
"id": "batch-uuid",
"status": "running",
"mode": "parallel",
"tasks": [...],
"prUrl": null,
"progress": {
"total": 5,
"completed": 2,
"failed": 0,
"running": 2,
"queued": 1,
"skipped": 0,
"cancelled": 0,
"percentage": 40
}
}