Skip to content

N+1 queries with cache_fragment and GraphQL Ruby Dataloader #126

@tsugitta

Description

@tsugitta

Summary

When using graphql-ruby (v2.4.8) together with graphql-fragment_cache (v1.20.5) on Rails 8.0.1, I encounter an unexpected N+1 query problem if I wrap a Dataloader-based field resolver with cache_fragment. Without cache_fragment, Dataloader batches the queries correctly. With cache_fragment, each user (in this example) triggers its own query, leading to N+1 behavior.

cache_fragment(expires_in: 1.minute) do
  dataloader.with(Sources::PostsByUser).load(object.id)
end

I have written an implementation and a test to illustrate the issue. Specifically:

  1. cache_fragment disabled: only 2 SQL SELECT statements (one for users, one for posts).
  2. cache_fragment enabled: 3 SQL SELECT statements (or more if more users are present), i.e., an N+1 pattern emerges.
=== Queries without cache ===
1. SELECT "users".* FROM "users" /*action='execute',application='GraphqlRubyIssueReproduction',controller='graphql',current_graphql_field='Query.users'*/
2. SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2) /*action='execute',application='GraphqlRubyIssueReproduction',controller='graphql',current_dataloader_source='Sources%3A%3APostsByUser'*/
=== Queries with cache ===
1. SELECT "users".* FROM "users" /*action='execute',application='GraphqlRubyIssueReproduction',controller='graphql',current_graphql_field='Query.users'*/
2. SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = 1 /*action='execute',application='GraphqlRubyIssueReproduction',controller='graphql',current_dataloader_source='Sources%3A%3APostsByUser'*/
3. SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = 2 /*action='execute',application='GraphqlRubyIssueReproduction',controller='graphql',current_dataloader_source='Sources%3A%3APostsByUser'*/

Environment

Rails: 8.0.1
Ruby: 3.3.2
graphql-ruby: 2.4.8
graphql-fragment_cache: 1.20.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions