Skip to content

Concurrency Control

GitHub Agentic Workflows uses dual-level concurrency control to prevent resource exhaustion and ensure predictable execution:

  • Per-workflow: Limits based on workflow name and trigger context (issue, PR, branch)
  • Per-engine: Limits AI execution across all workflows via engine.concurrency

Workflow-level concurrency groups include the workflow name plus context-specific identifiers:

Trigger TypeConcurrency GroupCancel In Progress
Issuesgh-aw-${{ github.workflow }}-${{ issue.number }}No
Pull Requestsgh-aw-${{ github.workflow }}-${{ pr.number || ref }}Yes (new commits cancel outdated runs)
Pushgh-aw-${{ github.workflow }}-${{ github.ref }}No
Schedule/Othergh-aw-${{ github.workflow }}No

This ensures workflows on different issues, PRs, or branches run concurrently without interference.

The default per-engine pattern gh-aw-{engine-id} ensures only one agent job runs per engine across all workflows, preventing AI resource exhaustion. The group includes only the engine ID and gh-aw- prefix - workflow name, issue/PR numbers, and branches are excluded.

jobs:
agent:
concurrency:
group: "gh-aw-{engine-id}"

Override either level independently:

---
on: push
concurrency: # Workflow-level
group: custom-group-${{ github.ref }}
cancel-in-progress: true
engine:
id: copilot
concurrency: # Engine-level
group: "gh-aw-copilot-${{ github.workflow }}"
tools:
github:
allowed: [list_issues]
---

The safe_outputs job runs independently from the agent job and can process outputs concurrently across workflow runs. Use safe-outputs.concurrency-group to serialize access when needed:

safe-outputs:
concurrency-group: "safe-outputs-${{ github.repository }}"
create-issue:

When set, the safe_outputs job uses cancel-in-progress: false — meaning queued runs wait for the in-progress run to finish rather than being cancelled. This is useful for workflows that create issues or pull requests where duplicate operations would be undesirable.

See Safe Outputs for details.