Expose per-user non-billable credits in the subscription usage API
What does this MR do and why?
The Total usage card on the GitLab Credits dashboard counts billable plus non-billable usage, but Usage by user and the user drill-down count billable usage only. The rows don't add up to the card, and users with only promotional usage (for example Orbit usage on an Orbit Promotional ELA subscription) aren't listed at all.
CustomersDot now returns a per-user nonBillableCreditsUsed next to the billable totalCreditsUsed (https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17683). This MR is the backend half of consuming it:
- Client:
GET_USERS_USAGE_QUERYandGET_CONSUMERS_QUERYselectnonBillableCreditsUsed. While CustomersDot hasn't deployed the field, the client retries without it, the same way it already does forentityType, so this MR can merge before the CustomersDot change is live. - GraphQL: new nullable
nonBillableCreditsUsedfield onGitlabSubscriptionUsageUserUsage, read from the CustomersDot response byUserConsumptionStatistics.totalCreditsUsedstays billable-only on both sides so the API keeps a clean billable / non-billable split; the frontend adds the two. - Credits sort:
UserUsage#users_sorted_by_credits_usedkeeps users whose billable + non-billable total is above 0, so promo-only users are listed. Until the frontend MR merges, such a user's row shows the billable0, because today's frontend only readstotalCreditsUsed. That window is GitLab.com only and short; the frontend MR is stacked on this one. - Specs, GraphQL docs and introspection schema.
Frontend (Usage by user row and drill-down card adding the two) is in !265553 (merged), stacked on this branch. Split on purpose: GitLab.com deploys in rolling fashion, so a frontend that selected the field in the same release could reach a node that doesn't serve it yet. @gl_introduced only covers the self-managed version skew, not that window.
This is change E (backend) of the plan in #633154 (comment 4099142904).
Not changed here: the credits sort still comes from CustomersDot's wallet debits, so users whose only usage is non-billable are listed but sort last. ConsumersFinder returns every consumer with no usage threshold, so they are reached by paging; the GitLab-side filter was what dropped them. A sort by billable plus non-billable is the iteration-2 follow-up in the issue (pre-existing issue 2).
References
- Related to #633154 (closed)
- Plan: #633154 (comment 4099142904)
- Frontend half: !265553 (merged)
- CustomersDot field (D): https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17683
- Total usage card change this aligns with: !260725 (merged)
Screenshots or screen recordings
| When CDot changes are NOT available | When CDot changes ARE available |
|---|---|
![]() |
![]() |
How to set up and validate locally
-
Check out https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17683 in your local CustomersDot. Without it, the client falls back to the billable-only queries and
nonBillableCreditsUsedisnull. -
Set up GDK in SaaS mode with that CustomersDot, as in "How to set up and validate locally" in !260725 (merged).
-
In CustomersDot, seed one user with billable and non-billable Orbit usage and another with non-billable usage only, then enrich and consume:
bin/populate_usage_data -r 20 --realm SaaS --root-namespace-id <id> --user-id <user_a> --feature-qualified-name orbit_mcp --team-member --skip-reason promo bin/populate_usage_data -r 20 --realm SaaS --root-namespace-id <id> --user-id <user_a> --feature-qualified-name orbit_rest bin/populate_usage_data -r 20 --realm SaaS --root-namespace-id <id> --user-id <user_b> --feature-qualified-name orbit_mcp --team-member --skip-reason promo -
In
/-/graphql-explorer, as a group owner:query { subscriptionUsage(namespacePath: "<group-path>") { usersUsage { users(sort: TOTAL_CREDITS_USED_DESC, first: 20) { nodes { username usage { totalCreditsUsed nonBillableCreditsUsed } } } } } } -
Both users are listed. User A has both figures; user B has
totalCreditsUsed: 0and a positivenonBillableCreditsUsed. Before this MR, user B was not returned.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

