Part of the desired behavior can be accomplished using runner groups. A GitHub runners group can have both GitHub hosted and self-hosted runners and a GitHub workflow job can be specified to run on a group:

    runs-on:
      group: hybrid-runners

If the hybrid-runners group have a self-hosted runner and a GitHub hosted runner, in each run, one of the runners will be used for that job. If the self-hosted runner is offline, then the job will necessarily default to the GitHub hosted runner.

AFAIK, there is no way to control a preferred runner and its unknown if GitHub already have a bias towards using GitHub hosted or self-hosted runners.

Answer from Diogo Melo on Stack Overflow
🌐
GitHub
docs.github.com › actions › using-github-hosted-runners › about-github-hosted-runners
GitHub-hosted runners - GitHub Docs
For example, Ubuntu and macOS runners include grep, find, and which, among other default tools. You can also view a software bill of materials (SBOM) for each build of the Windows and Ubuntu runner images.
🌐
GitHub
docs.github.com › en › actions › reference › runners › github-hosted-runners
GitHub-hosted runners reference - GitHub Docs
Find information about GitHub-hosted runners, including their specifications and customization options.
🌐
GitHub
docs.github.com › actions › using-jobs › choosing-the-runner-for-a-job
Choosing the runner for a job - GitHub Docs
The runs-on key sends the job to any available runner in the ubuntu-runners group: name: learn-github-actions on: [push] jobs: check-bats-version: runs-on: group: ubuntu-runners steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: '14' - run: npm install -g bats - run: bats -v
🌐
GitHub
docs.github.com › actions › hosting-your-own-runners
Self-hosted runners - GitHub Docs
You can host your own runners and customize the environment used to run jobs in your GitHub Actions workflows.
🌐
GitHub
docs.github.com › en › actions › concepts › runners
GitHub Actions Runners - GitHub Docs
You can host your own runners and customize the environment used to run jobs in your GitHub Actions workflows.
🌐
GitHub
github.com › actions › runner-images
GitHub - actions/runner-images: GitHub Actions runner images · GitHub
This repository contains the source code used to create the VM images for GitHub-hosted runners used for Actions, as well as for Microsoft-hosted agents used for Azure Pipelines.
Starred by 12.6K users
Forked by 3.7K users
Languages   PowerShell 65.4% | Shell 22.4% | HCL 11.4% | Python 0.2% | Dockerfile 0.2% | Swift 0.2% | AppleScript 0.2%
Find elsewhere
🌐
Neon
neon.com › guides › gihub-actions-self-hosted-runners
How to use self-hosted runners with GitHub Actions - Neon Guides
March 1, 2025 - In this step, you'll create a new user named runneruser and grant it the necessary privileges to function as a self-hosted runner for GitHub Actions. In your terminal, run the following command to create the runneruser and set a password. ... You'll be asked to re-enter the password. For the following prompts, you can simply press ENTER to accept the default values for fields like Full Name, Room Number, Work Phone, and so on.
🌐
GitHub
github.blog › home › changelogs › deprecation of node 20 on github actions runners
Deprecation of Node 20 on GitHub Actions runners - GitHub Changelog
September 19, 2025 - We plan to migrate all actions to run on Node24 in the fall of 2026. The newest GitHub runner (v2.328.0) now supports both Node20 and Node24 and uses Node20 as the default version.
🌐
DEV Community
dev.to › busycaesar › configure-self-hosted-runner-for-github-actions-j1b
Configure self-hosted runner for GitHub Actions - DEV Community
January 25, 2025 - ./config.sh --url [GitHub Repo URL] --token [GitHub Repo Token] Entering the above commands prompts you the following questions, Enter the name of the runner group to add this runner to: You can add this runner to any group that you want to or simply press enter to add it to a default group.
🌐
GitHub
docs.github.com › actions › hosting-your-own-runners › managing-self-hosted-runners › adding-self-hosted-runners
Adding self-hosted runners - GitHub Docs
For information about how to add a self-hosted runner with the REST API, see REST API endpoints for self-hosted runners. On GitHub, navigate to the main page of the organization. Under your organization name, click Settings. If you cannot see the "Settings" tab, select the dropdown menu, then click Settings. In the left sidebar, click Actions, then click Runners.
🌐
Medium
medium.com › @chandika.s › github-actions-essentials-understanding-github-runners-in-github-actions-0102aefd73b1
📊 “GitHub Actions Essentials: Understanding GitHub Runners in GitHub Actions 🚀 | by Chandika S | Medium
December 6, 2023 - /github/workspace — Note: GitHub Actions must be run by the default Docker user (root). Ensure your Dockerfile does not set the USER instruction, otherwise, you will not be able to access $GITHUB_WORKSPACE ...
🌐
GitHub
docs.github.com › en › actions › reference › runners › self-hosted-runners
Self-hosted runners reference - GitHub Docs
GitHub-hosted runners can be a low-maintenance and cost-effective alternative to developing or implementing autoscaling solutions. For more information, see GitHub-hosted runners. Actions Runner Controller (ARC) is the reference implementation of GitHub's scale set APIs and the recommended Kubernetes-based solution for autoscaling self-hosted runners.
🌐
GitHub
docs.github.com › en › actions › how-tos › manage-runners › self-hosted-runners › use-in-a-workflow
Using self-hosted runners in a workflow - GitHub Docs
This example shows a job that combines default and custom labels: ... gpu - This custom label has been manually assigned to self-hosted runners with the GPU hardware installed. These labels operate cumulatively, so a self-hosted runner must have all four labels to be eligible to process the job. In this example, Ubuntu runners have been added to a group called ubuntu-runners. The runs-on key sends the job to any available runner in the ubuntu-runners group: name: learn-github-actions on: [push] jobs: check-bats-version: runs-on: group: ubuntu-runners steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: '14' - run: npm install -g bats - run: bats -v
🌐
Zenn
zenn.dev › cybozu_ept › articles › productivity-weekly-20240403
GitHub-hosted runner強化イベント複数|Productivity Weekly(2024-04-03)
April 3, 2024 - GitHub Actions において、ワークフローやジョブが Organization 内のどこでどれだけ実行されているかを知れるダッシュボード Actions Usage Metrics が public beta としてリリースされました。GitHub Enterprise Cloud 利用者のみが利用可能です。
🌐
GitHub
docs.github.com › articles › getting-started-with-github-actions
Understanding GitHub Actions - GitHub Docs
Each step is either a shell script that will be executed, or an action that will be run. Steps are executed in order and are dependent on each other. Since each step is executed on the same runner, you can share data from one step to another. For example, you can have a step that builds your application followed by a step that tests the application that was built. You can configure a job's dependencies with other jobs; by default, jobs have no dependencies and run in parallel.
🌐
GitHub
docs.github.com › en › actions › hosting-your-own-runners › managing-self-hosted-runners
Managing self-hosted runners - GitHub Docs
You can configure the self-hosted runner application as a service to automatically start the runner application when the machine starts.
🌐
GitHub
docs.github.com › en › actions › learn-github-actions › variables
Store information in variables - GitHub Docs
March 27, 2023 - In this example, the workflow specifies ubuntu-latest. By default, Linux runners use the bash shell, so you must use the syntax $NAME. By default, Windows runners use PowerShell, so you would use the syntax $env:NAME.