Skip to content

Dataloader perf report #5431

@gmac

Description

@gmac

As promised, here's the result of using Dataloader with a flat execution map... methodology:

SDL = %|
  type Query {
    test: String
  }
|
GEM_RESOLVERS = {
  "Query" => {
    "test" => ->(obj, _args, _ctx) { obj["test"] },
  },
)
GRAPHQL_GEM_SCHEMA = Schema.from_definition(SDL, default_resolve: GEM_RESOLVERS)
GRAPHQL_GEM_SCHEMA_DL = Schema.from_definition(SDL, default_resolve: GEM_RESOLVERS)
GRAPHQL_GEM_SCHEMA_DL.use(GraphQL::Dataloader)

root_value = { "test" => "zebra" }

Benchmark.ips do |x|
  x.report("graphql-ruby: #{num_fields} fields") do
    GRAPHQL_GEM_SCHEMA.execute(document: DOCUMENT, root_value: root_value, validate: false)
  end

  x.report("graphql-ruby dataloader: #{num_fields} fields") do
    GRAPHQL_GEM_SCHEMA2.execute(document: DOCUMENT, root_value: root_value, validate: false)
  end
  x.compare!
end

We do the above running a document with reasonable complexity of various sizes, you can see the exact data structure in the Cardinal prototype repo, it's a bunch of products with a bunch of child variants each. We ramp up the object counts as we go. Looks like Dataloader is about ~1.4x slower at this flat execution task of all CPU-bound work (running YJIT):

ruby 3.4.4 (2025-05-14 revision a38531fd3f) +YJIT +PRISM [arm64-darwin24.4.0]
Warming up --------------------------------------
graphql-ruby: 394 fields
                       201.000 i/100ms
graphql-ruby dataloader: 394 fields
                       150.000 i/100ms
Calculating -------------------------------------
graphql-ruby: 394 fields
                          2.013k (± 2.1%) i/s  (496.73 μs/i) -     10.251k in   5.094254s
graphql-ruby dataloader: 394 fields
                          1.480k (± 1.9%) i/s  (675.73 μs/i) -      7.500k in   5.069792s

Comparison:
graphql-ruby: 394 fields:     2013.2 i/s
graphql-ruby dataloader: 394 fields:     1479.9 i/s - 1.36x  slower

ruby 3.4.4 (2025-05-14 revision a38531fd3f) +YJIT +PRISM [arm64-darwin24.4.0]
Warming up --------------------------------------
graphql-ruby: 3141 fields
                        25.000 i/100ms
graphql-ruby dataloader: 3141 fields
                        18.000 i/100ms
Calculating -------------------------------------
graphql-ruby: 3141 fields
                        247.785 (± 8.1%) i/s    (4.04 ms/i) -      1.225k in   5.001154s
graphql-ruby dataloader: 3141 fields
                        183.953 (± 2.2%) i/s    (5.44 ms/i) -    936.000 in   5.091283s

Comparison:
graphql-ruby: 3141 fields:      247.8 i/s
graphql-ruby dataloader: 3141 fields:      184.0 i/s - 1.35x  slower

ruby 3.4.4 (2025-05-14 revision a38531fd3f) +YJIT +PRISM [arm64-darwin24.4.0]
Warming up --------------------------------------
graphql-ruby: 31131 fields
                         2.000 i/100ms
graphql-ruby dataloader: 31131 fields
                         1.000 i/100ms
Calculating -------------------------------------
graphql-ruby: 31131 fields
                         25.549 (± 3.9%) i/s   (39.14 ms/i) -    128.000 in   5.014638s
graphql-ruby dataloader: 31131 fields
                         18.613 (± 5.4%) i/s   (53.73 ms/i) -     93.000 in   5.009211s

Comparison:
graphql-ruby: 31131 fields:       25.5 i/s
graphql-ruby dataloader: 31131 fields:       18.6 i/s - 1.37x  slower

ruby 3.4.4 (2025-05-14 revision a38531fd3f) +YJIT +PRISM [arm64-darwin24.4.0]
Warming up --------------------------------------
graphql-ruby: 311031 fields
                         1.000 i/100ms
graphql-ruby dataloader: 311031 fields
                         1.000 i/100ms
Calculating -------------------------------------
graphql-ruby: 311031 fields
                          2.482 (± 0.0%) i/s  (402.88 ms/i) -     13.000 in   5.242374s
graphql-ruby dataloader: 311031 fields
                          1.642 (± 0.0%) i/s  (608.90 ms/i) -      9.000 in   5.500123s

Comparison:
graphql-ruby: 311031 fields:        2.5 i/s
graphql-ruby dataloader: 311031 fields:        1.6 i/s - 1.51x  slower

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions