Workflow queue backlog - too many jobs waiting for runners
Workflow runs show 'Queued' status for many minutes before starting
Focused incident mode — strips away everything but this runbook.
Symptoms
- Workflow runs show 'Queued' status for many minutes before starting
- Total workflow duration is 20+ minutes but the actual job runs in 3 minutes
- Multiple workflows pile up in the queue simultaneously
Free GitHub accounts have a 20-concurrent-job limit. If your org has 5 repos each running 5 jobs on every push, you will hit the limit immediately.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Queued runs count
gh run list --repo <OWNER/REPO> --status queued --limit 20 --json name,createdAtConcurrency limits
cat .github/workflows/<file>.yml | grep -A5 'concurrency:'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- Free plan has 20 concurrent jobs; 25+ jobs are queued
- Multiple repositories in the org are running CI simultaneously
Confirm before fixing
gh api /orgs/<OWNER>/settings/billing/actions --jq '.included_minutes'Check plan concurrency limit
Fix
echo 'Upgrade plan or add self-hosted runners at https://github.com/settings/billing'Increase concurrency by upgrading or adding self-hosted runners
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
gh run list --repo <OWNER/REPO> --status queued --limit 20 --json name,createdAtSee what is queued
gh run cancel <RUN_ID>Cancel redundant queued runs to free slots
cat .github/workflows/<file>.yml | grep -A10 'strategy:'Review matrix size
Prevention
- Use concurrency groups to cancel superseded runs on the same branch.
- Reduce matrix dimensions for non-release workflows.
- Use path filters to skip CI on docs-only changes.
- Add self-hosted runners for high-volume CI workloads.
Related runbooks
Same stack, same failure family — worth a skim.
Workflow runs queued with 'Waiting for a runner to pick up this job'
All new workflow runs immediately fail with 'Your GitHub Actions minutes have been used up'
Previously in-progress workflow shows 'Cancelled' when a new push arrives
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.