Graphql N+1 Triage: getProjectsMergeRequestNotes

Summary

getProjectsMergeRequestNotes ranked among the top N+1 candidates on gitlab.com, based on 24 hours of production log data. It's estimated to cost 305.1 avoidable queries per minute. See https://gitlab.com/groups/gitlab-org/-/epics/23614 for how this list was built and the method to follow.

Numbers

Metric Value
Requests in 24h 22,831
N+1 risk 0.98
p95 queries on main replica 1232
p95 DB duration (s) 3.589
Estimated savings per minute 305.1

Where the query comes from

No .graphql file in gitlab-org/gitlab defines this operation, so it comes from an external client (IDE extension, CLI, or a third-party API user). Reconstruct the selection from json.graphql.used_fields in Kibana.

Primary type read, inferred from the operation name: MergeRequest. Owning group: group::code review.

What to do

  1. Find the query source: the .graphql file in the repo, or json.graphql.used_fields in Kibana for external clients.
  2. Write a throwaway request spec, run it against a small and a larger page, and record queries with ActiveRecord::QueryRecorder.new(skip_cached: false).
  3. Fix per-row growth with lookahead preloads, BatchLoader::GraphQL, or a policy preloader in before_connection_authorization.
  4. Add a permanent N+1 spec that asserts query counts don't grow with page size.
  5. After deploy, confirm the savings estimate dropped in the Lens table.

Acceptance criteria

  • Per-row queries identified and listed in this issue.
  • Fix merged.
  • Permanent N+1 spec added.
  • Savings in the Lens table dropped after deploy, or this issue is closed with an explanation of why the spread is fixed cost.
Edited by Eduardo Bonet