Skip to main content
By default, there is no queuing or ordering for jobs: as soon as a job is scheduled a runner is started for it. This changes when your workspace is hitting concurrency limits and jobs have to wait for resources to become available. Namespace offers controls to influence the order of jobs to be picked up. See the Runner Controls overview for how to pass these settings via a profile or labels.

Deterministic assignments

By default, a job can be assigned to any runner that matches that job’s labels. A runner will pick up the job that it’s assigned by GitHub, which does not happen in order. This means that while hitting concurrency limits, jobs with the same labels might not be executed in the expected order. As a consequence, a runner that was started for one job may never pick up a job at all, because another matching runner got there first. Such instances are not billed, see Billing and Limits. To control this behaviour, you can add the run id to the labels. Then only that specific job can be picked up by the runner started for it, and jobs are executed in the order in which they are scheduled:

Job priority

When some workflows should not be blocked by other less, time-sensitive ones, you can assign them a priority. Priority only affects scheduling while running into concurrency limits. Pending jobs with the lowest numbers will be started first. Jobs with any priority specified take precedence over those without. To specify a priority, append job.priority=<number> to the runs-on label:

Next steps

Last modified on September 15, 2026