What are the different types of GitLab Runners (shared, specific, and group) and when would you use each?
Quick Answer
Shared Runners are available to all projects in a GitLab instance and managed by admins. Specific (project) Runners are dedicated to one project for isolation or compliance. Group Runners are shared across all projects within a group, balancing resource sharing with organizational boundaries.
Detailed Answer
Think of GitLab Runners like different tiers of taxis in a city. Shared Runners are the public taxi fleet available to anyone hailing a cab on any street (any project in the instance). Group Runners are like a corporate car service that serves only employees of a specific company division (projects within a group). Specific Runners are personal chauffeurs assigned to one VIP client (a single project), guaranteeing availability and a clean vehicle every time.
GitLab Runners are the agents that actually execute CI/CD jobs. When a pipeline is created, jobs are placed in a queue and Runners poll the GitLab server for work matching their scope and tags. Shared Runners are registered at the instance level by a GitLab administrator and are available to every project across the entire GitLab installation. They use a fair-usage queue that distributes jobs evenly across projects so that one project with a hundred pipelines cannot starve another project of resources. Group Runners are registered at the group level and serve all projects within that group and its subgroups. They are ideal when a department or team wants dedicated compute capacity without giving every project its own Runner. Specific Runners are locked to a single project, meaning they will only pick up jobs from that project. They offer maximum isolation and are commonly used when a project requires special hardware (GPUs for ML training), has compliance requirements (HIPAA data that cannot be processed on shared infrastructure), or needs guaranteed capacity for time-sensitive deployments.
Internally, Runner registration involves generating a token at the desired scope (instance, group, or project) and using it with the gitlab-runner register command. Each Runner stores its configuration in a config.toml file that defines the executor type (shell, docker, docker+machine, kubernetes, custom), concurrency limits, and default settings. When a Runner polls for jobs, it sends its token and tags to the GitLab API. The coordinator matches available jobs to Runners based on three criteria: scope (is this Runner authorized for the project?), tags (does the job require tags that the Runner provides?), and protected status (if the Runner is protected, it only runs jobs from protected branches or tags). The fair-usage queue for shared Runners works by tracking the last time each project used the shared Runner fleet and prioritizing projects that have waited the longest.
In production, organizations typically deploy a layered Runner strategy. A fintech company running payment-processing-api might configure shared Runners with tags like docker and linux for general-purpose CI jobs across all teams. The data-engineering group registers group Runners on GPU-equipped machines tagged ml-training for their model training pipelines. The compliance-sensitive audit-trail-service gets its own specific Runner on a hardened VM in a private subnet, tagged secure and isolated, ensuring no other project's code ever executes on that machine. The Runner fleet is usually managed using Infrastructure as Code with Terraform, deploying Runner instances on AWS EC2 or GCP Compute Engine with autoscaling groups. The docker+machine executor can spin up ephemeral VMs for each job, ensuring clean environments and enabling burst capacity during peak hours.
A critical gotcha is the interaction between Runner tags and job tag requirements. If a job specifies tags but no Runner with matching tags is available, the job will be stuck in pending state indefinitely, with no clear error message in the pipeline view. Conversely, if you have shared Runners enabled and a job has no tags, it will run on any available shared Runner, which might be in a different region or have different capabilities than expected. Always audit your Runner registrations with gitlab-runner list and verify tag assignments. Another common mistake is not setting the lock_to_current_project option on specific Runners, which could allow an admin to reassign them to other projects accidentally.