Can I Run More Jobs Than My Plan Allows?

Yes. The concurrent job ceiling on your GitHub plan counts jobs on GitHub-hosted labels only, so jobs routed to warp- labels queue on WarpBuild capacity.

Answer

Yes, because the concurrent job ceiling attached to your GitHub plan counts jobs running on GitHub-hosted runners, and it stops counting at the point where a job is dispatched somewhere else. That ceiling runs from 20 concurrent jobs on Free to 500 on Enterprise with a lower macOS sub-ceiling, per GitHub's usage limits reference, checked on 2026-08-13; a job whose runs-on value resolves to a warp- label is handed to a WarpBuild runner and queues on WarpBuild capacity instead.

The boundary is drawn per job, by the runs-on value on that job. There is no account setting and no plan upgrade involved. Two jobs in the same workflow file can sit on opposite sides of it.

Where the job runsDraws from the GitHub plan ceilingWhat decides when it starts
ubuntu-latest, windows-latest, macos-latest and other GitHub-hosted labelsYesFree slots under your plan ceiling
warp- labelsNoWarpBuild pool capacity for that label
Self-hosted labels you register yourselfNoCount of matching runners you keep online

Per the cloud runners documentation. Run as many jobs as your workflows need. Generally available Linux and Windows runners do not have plan-level concurrency caps. That statement carries the scope written in the same documentation: features that are Generally Available support unlimited concurrency on Linux and Windows runners, and features in beta may carry limits. macOS runs on a per-organization quota, so teams that need high macOS concurrency arrange it with support at [email protected]. Slack support channels are also available on demand, per the pricing page.

Detail

Move the fan-out, keep the rest

Routing per job means the migration is a label change on the jobs that fan out. The workflow below keeps a single lint job on the GitHub-hosted pool and sends a 40-way integration matrix to warp-ubuntu-latest-x64-4x, so exactly one job in this file draws from the plan ceiling.

name: integration

on:
  pull_request:
  push:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run lint

  integration:
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        suite: [api, web, worker, jobs]
    runs-on: warp-ubuntu-latest-x64-4x
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run test:${{ matrix.suite }} -- --shard=${{ matrix.shard }}/10

The matrix produces 10 shards by 4 suites, so 40 jobs are eligible to start together. On a Free-plan account with a 20-job ceiling, the same 40 jobs on ubuntu-latest would run in two waves. Nothing else in the file changes: the same steps, the same actions, the same Node version.

Limits that survive the move

Three limits belong to the repository or the workflow rather than to the runner, and they hold after the labels change. All three were checked on 2026-08-13 against GitHub's usage limits reference.

  • 256 jobs per matrix per workflow run. The matrix above sits at 40. Past 256, split the suite across workflows or collapse a dimension.
  • The concurrency key you wrote. A group holds one running item and one pending item regardless of which runner the work lands on. The guide to GitHub Actions concurrency limits covers the group shapes that serialize a workflow by accident.
  • 24 hours of queue time. A job waiting on a self-hosted or managed runner is dropped after 24 hours.

A fourth failure mode looks like a capacity problem and is a routing problem: a job whose labels match zero online runners waits without logs. Check the label spelling and the runner group permissions in the common issues documentation before you conclude that a pool is full.

What the extra parallelism costs

Assume the 40 integration jobs above each take 5 minutes, with no retries. Total compute is 200 job-minutes per run whether those jobs run in one wave or two, so the fan-out buys back wall clock and leaves billed minutes alone.

Slots availableWavesWall clock per runBilled job-minutes
20210 min200
4015 min200

Priced at the catalog rate for warp-ubuntu-latest-x64-4x, 200 minutes at $0.008 per minute is $1.60 per run. At 300 pull request runs a month that is 60,000 job-minutes and $480.00, and the second row returns 5 minutes of wall clock on every one of those runs.

runs-on labelvCPURAMRate per minute
warp-ubuntu-latest-x64-2x28GB$0.004
warp-ubuntu-latest-x64-4x416GB$0.008
warp-ubuntu-latest-arm64-4x416GB$0.006
warp-windows-latest-x64-4x416GB$0.016
warp-macos-latest-arm64-6x622GB$0.080

Full per-minute rates by runner type are on the pricing page.

Confirm the ceiling moved

Measure queue wait per runner label before and after the label change rather than reading the running job count alone. A label whose P90 queue wait stays flat while the number of jobs running together climbs past the old plan ceiling is the signal that the ceiling stopped binding. A P90 that climbs on one label while other labels start on time points at capacity for that label. The guide to GitHub Actions queue times walks through each reading and the fix that matches it.

Which jobs count against my GitHub plan ceiling?

Jobs whose runs-on resolves to a GitHub-hosted label such as ubuntu-latest, windows-latest, or macos-latest. The ceiling runs from 20 concurrent jobs on Free to 500 on Enterprise, checked on 2026-08-13 against GitHub's usage limits reference. Jobs that target warp- labels are dispatched to WarpBuild runners and queue on WarpBuild capacity instead. The full breakdown of every ceiling between a queued job and a running one is in how many GitHub Actions jobs can run at once.

Do I have to move every job to raise the ceiling?

No. Routing is per job, so a workflow can keep a small lint job on ubuntu-latest and send a 40-way test matrix to warp-ubuntu-latest-x64-4x. Only the jobs still on GitHub-hosted labels draw from the plan ceiling after that, which makes the migration reversible one job at a time.

Which limits still apply after the move?

Repository-level limits stay in force. A matrix still generates at most 256 jobs per workflow run, your concurrency key still throttles the groups you named, and a job queued for a self-hosted or managed runner is dropped after 24 hours. The guide to GitHub Actions concurrency limits maps each of those to the symptom it produces.

Price your own fan-out against the per-minute rates on the pricing page, then change the runs-on value on one matrix job and watch where the queue moves.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.