Preload merge request authors for project pipelines

What does this MR do and why?

The ProjectPipelines GraphQL query runs more users queries as the number of merge request authors grows. This MR preloads the author and target project of each merge request, so the query count no longer depends on the authors.

  • The lookahead preload for the mergeRequest field in Resolvers::Ci::ProjectPipelinesResolver now loads { merge_request: [:author, :target_project] } instead of only :merge_request.
  • This is the same pair the merge request GraphQL resolvers (MergeRequests::LookAheadPreloads#unconditional_includes) and the REST user pipelines API (Ci::Pipeline.with_user_pipelines_api_associations) already preload.
  • A new request spec example adds two merge request pipelines with different authors.
  • No feature flag: it is a plain preload of existing associations that REST already uses.
  • No database review needed: these are primary-key IN lookups on users and projects.

Before the change, adding two merge request pipelines with new authors went from 40 to 44 queries in that spec (cached queries included). After it, the count stays the same.

A separate MR batches the jobs of CI stages for the same query.

Why this happens and how it was measured
  • The external ProjectPipelines query on GitLab.com selects mergeRequest { iid } on every node of project.pipelines. It had 120,296 requests on 2026-09-16, with p95 at 319 queries on the main replica.
  • MergeRequestType authorizes each merge request with read_merge_request. MergeRequestPolicy prevents it for hidden merge requests. MergeRequest#hidden? reads author&.banned?, so the policy loads each author. The policy subject is the merge request's target_project.
  • The resolver preloaded only merge_request. So each distinct author cost one users query, and each merge request one (SQL-cached) projects lookup.
  • The existing N+1 shared example for merge request fields did not catch this. All its merge requests share the factory default author (the project creator).
  • Measured in the new spec, with cached queries included: 40 queries before adding two merge request pipelines with new authors, 44 after, without the fix. With the fix the count stays the same.

References

Screenshots or screen recordings

This does not apply. The change is backend-only and has no UI change.

How to set up and validate locally

  1. Open GraphiQL at /-/graphql-explorer on a project with several merge request pipelines whose merge requests have different authors.

  2. Run this query, replacing the project path:

    query {
      project(fullPath: "<project path>") {
        pipelines(first: 20) {
          nodes { id mergeRequest { iid } }
        }
      }
    }
  3. Open the performance bar and check the users queries for the request.

  4. Confirm the number of users queries does not grow with the number of merge request authors.

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.

Merge request reports

Loading
Loading