Add GQL API to fetch dedicated hosted runner usage
What does this MR do and why?
This merge request introduces a new GraphQL query for retrieving compute usage data for dedicated hosted runners in GitLab. It adds a new resolver, types, and database scopes to support querying usage data either aggregated at the instance level or grouped by root namespace. The changes include new GraphQL fields, arguments, and enums to allow flexible querying of usage data by billing month or year.
Additionally, it implements authorization checks to ensure only admin users on GitLab Dedicated instances can access this data. The merge request also includes corresponding test coverage for the new functionality.
References
Please include cross links to any resources that are relevant to this MR. This will give reviewers and future readers helpful context to give an efficient review of the changes introduced.
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Query plans
Since this API is Dedicated specific, the data in production tables for .com is empty, but I still want to share the query plans for database review. I added around 700k rows to this table and generated the below query plans.
For INSTANCE_AGGREGATE grouping
Plan for billingMonth filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111397
Plan for year filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111396
For PER_ROOT_NAMESPACE grouping
Plan for billingMonth filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111398
Plan for year filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111399
Screenshots or screen recordings
How to set up and validate locally
- Create some usage entries by using the below rails console command.
Ci::Minutes::GitlabHostedRunnerMonthlyUsage.create!(
billing_month: Date.new(2025, 2, 1),
compute_minutes_used: 100.0, # Replace with the desired value
runner_duration_seconds: 6000, # Replace with the desired value
root_namespace: Namespace.first, # Replace with the desired namespace
runner: Ci::Runner.first, # Replace with the desired runner
project: Project.first # Replace with the desired project
)
-
Enable GitLab dedicated setting with -
Gitlab::CurrentSettings.update(gitlab_dedicated_instance: true) -
Use the below query as per filters in screenshots -
query {
ciDedicatedHostedRunnerUsage(grouping: <GroupingEnum>,
year: <YearFilter> # or billingMonth: "2025-01-01") {
nodes {
billingMonth
billingMonthIso8601
computeMinutes
durationSeconds
rootNamespace {
id
name
}
}
}
}
- The above steps should get you the data at instance level and at root namespace level in the response.



